calculate the modulus of a fraction with big numbers - java

I have two big numbers (<10^9) n and m. I have to calculate [(n-1+m)!]/[(n-1)!*m!]
if the answer is too big I have to get the modulus from (10^9+7). (ex : n%mod if n is too large that mod).
int mod = 1000000000+7;
I calculated it like below. (I calculated the upper half and bottom half separately)
long up=1;
for (long i = a+b-1; i>=Math.max(a, b); i--) {
up*=i%mod;
}
up=up%mod;
long down=1;
for (long i = Math.min(a, b); i>0; i--) {
down*=i%mod;
}
then print the answer as
System.out.println((up%mod/down%mod)%mod);
Is this approach correct. Will it gives the correct out put.
I know (a*b*c)%d == [(a%d)*(b%d)*(c%d)]%d (correct me if i'm wrong)
So is there any way like that to calculate [a/b]%d ?

(a/b) % c != ((a%c) / (b%c) % c)
Instead use recursive formula of binomial coefficient to calculate the modulus
(n, k) = (n - 1, k - 1) + (n - 1, k)
In your case it will be
(n - 1 + m, m) % MOD = ((n - 2 + m, m - 1) % MOD + (n - 2 + m, m) % MOD) % MOD
use above recursion to get the result.

Related

please translate this python code into java for this question and explain what its internal works [duplicate]

this is so far all i have done
i am trying to optimize the code for less time.but it is not working.
for _ in range(int(input())):
n, m = map(int, input().split())
count = 0
for i in range(1, n+1):
for j in range(1, n+1):
if i < j <= n and ((m%i)%j) == ((m%j)%i):
count += 1
print(count)
another approach I tried:
if i < j <= n and (m-(m%j))%i == 0:
both condition give correct result.but show time limit exceed
what should i do.thanks
Since a < b, we infer that (M mod a) mod b = M mod a, so the condition is equivalent to M mod a = (M mod b) mod a, i.e., M − (M mod b) is a multiple of a. We can iterate over all b and count factors of M − (M mod b) using a sieve, resulting in a Θ(N + M log N)-time algorithm.
N = 2304
M = 23498
def fast():
npairs = 0
nfactors = [1] * (M + 1)
for b in range(2, N + 1):
npairs += nfactors[M - M % b]
for i in range(0, M + 1, b):
nfactors[i] += 1
return npairs
def naive():
return sum((M % a) % b == (M % b) % a for b in range(2, N + 1) for a in range(1, b))
print(fast(), naive())
Think of it like x%mod(a) is same as x%mod(b) only condition a<b and if mod(b) is calculated, don't need to calculate mod(a) again if its already stored .
(n-1) is for all the pairs of 1's
for _ in range(int(input())):
n,m=map(int,input().split())
count=0
dictitems=defaultdict(int)
for i in range(2,n+1):
rem=m%i
count+=dictitems[rem]
for j in range(rem,n+1,i):
dictitems[j]+=1
print(count+(n-1))
Your approach is a good start but takes exactly N * N iterations.
You can start with following improvements.
sort the data
Using 2 pointer approach with optimised search range for second pointer
for i in range(1, n+1):
for j in range(i+1, n+1): # note j start at `i+1`

Sum of squares of digits of an integer in Java

I am trying to write a recursive implementation of a method that takes a non-negative argument, and returns the sum of the squares of its digits. For example, sumSquareDigits(10) should return 1 and sumSquareDigits(103) should return 10.
This is my code :
public static int sumSquareDigits(int n) {
if (n < 10) return n^2;
return (((n % 10)^2) + sumSquareDigits(n/10));
}
For example for an given integer 625, it would be something like:
(625 % 10)^2 + (62,5 % 10)^2 + (6,25)^2 = 5^2 + 2^2 + (6,25)^2
which of course is wrong because the last term should be 6 and not 6,25. What I am looking for is a way to truncate 6,25 so that it becomes 6.
How do we do this? And I'd appreciate any hints to implement this function better (I'm new in Java).
Thanks!
In Java, ^ is not "to the power" of, it is the bitwise XOR operator. To perform powers in Java use Math.pow. Bear in mind that Math.pow returns a double so you will need to cast it to an int if you only want a whole number. E.g.
if (n < 10) return (int)Math.pow(n, 2);
Of course, as msandiford pointed out, if you only need to calculate powers of 2, it is probably easier to just multiply a number by itself. E.g.
if (n < 10) return n * n;
The ^ is for the bitwise XOR operator. You could use Math.pow, and cast the results to int since Math.pow returns a double:
public static int sumSquareDigits(int n) {
if (n < 10) return (int) Math.pow(n, 2);
return (int)((Math.pow((n % 10), 2)) + sumSquareDigits(n/10));
}
Or since it's only squared, just multiply the base by itself:
public static int sumSquareDigits(int n) {
if (n < 10) return n * n;
return ((n % 10) * (n % 10)) + sumSquareDigits(n/10);
}

Return a large power (mod 2^32)

I need to work out a very large power modulo (2^32), i.e. I want the result of:
y = (p^n) mod (2^32)
p is a prime number
n is a large integer
Is there a trick to doing this efficiently in Java?
Or am I stuck with doing it in a loop with n iterations?
The simple way to mod 2^32 is to use & 0xFFFFFFFFL. Also, there happens to be a type which naturally keeps the lowest 32-bit called int ;) If you use that you don't even need to perform the & until you have the result (so the answer is unsigned) For this reason you only need to keep the last 32 bit of the answer. To speed up the ^n you can calculate the square, it's square and it's square etc, e.g if n is 0b11111 then you need to multiply p^16 * p^8 * p^4 * p^2 * p.
In short, you can use plain int as you only need 32-bit of accuracy and values with a cost of O(ln n) where n is the power.
int prime = 2106945901;
for (int i = 0; i < 10; i++) {
long start = System.nanoTime();
long answer1 = BigInteger.valueOf(prime)
.modPow(
BigInteger.valueOf(prime),
BigInteger.valueOf(2).pow(32)).longValue();
long mid = System.nanoTime();
int answer2 = 1;
int p = prime;
for (int n = prime; n > 0; n >>>= 1) {
if ((n & 1) != 0)
answer2 *= p;
p *= p;
}
long end = System.nanoTime();
System.out.printf("True answer %,d took %.3f ms, quick answer %,d took %.3f ms%n",
answer1, (mid - start) / 1e6, answer2 & 0xFFFFFFFFL, (end - mid) / 1e6);
}
prints finally
True answer 4,169,684,317 took 0.233 ms, quick answer 4,169,684,317 took 0.002 ms
You can utilize exponentiation by squaring. Firstly, break it down into powers of two for your given n. Since p^n (mod x) == p^(k1) (mod x) . p^(k2) (mod x) . ... p^(kn) (mod x) where sum k_i = n, you can utilize this and successive powers of two to calculate this in O(log n) steps.
In addition to the other answers you can use some elementary number theory to reduce the time needed to compute an mod 232 for a an odd integer to O(1). The Euler Phi function together with Euler's Theorem allows you to discard all but the low-order 31 bits of n.
φ(232) = 231, and aφ(232) = 1 mod 232.
Thus if n = q*(231) + r, 0 <= r < 231, then an mod 232 = ar mod 232
r is simply the low-order 31 bits of n, i.e. n & 0x7fffffff. In fact, by Carmichael's Theorem you can do a bit better (literally), and you only need to consider the low-order 30 bits of n, i.e. n & 0x3fffffff. You can precompute these once and store them in a table of size 4GB for a given base a. Here is some java code as an example.
import java.math.BigInteger;
public class PowMod2_32 {
private static final long MASK32 = 0xffffffffL;
public static long pow32(final int a, final int exponent)
{
int prod = 1;
for (int i = 29; i>=0; i--) {
prod *= prod; // square
if (((exponent >> i) & 1) == 1) {
prod *= a; // multiply
}
}
return prod & MASK32;
}
public static long pow32(BigInteger a, BigInteger exponent) {
return pow32(a.intValue(), exponent.intValue());
}
}
There are no tricks in java that I know of but rather there are some tricks in maths.
If you implement these as an algorithm it should speed up computation.
Look at 5 and 6. Look at 4 also if power of two is always even
Use the Class Bigintiger. here´s an example how to work / pow with it
public String higherPow() {
BigIntiger i = new Bigintger("2");
// doing a power(2^32)
i = i.pow(32);
// after 2^32 was made, do mod 100
i = i.mod(new Bigintiger("100"));
return i.toString();
}

How to determine big O of something that looks like this: (x -1) + (x - 2) + (x - 3) ... (x - x)

I'm trying to brush up on my big o calculations. If I have function that shifts all of the items to the right of 'i' 2 spaces I have a formula that looks something like:
(n -1) + (n - 2) + (n - 3) ... (n - n)
Where the first iteration I have to move (x-1) items, the second (x-2) items, and so on...
the method:
int[] s = {1,2,3,4, , }
public static char[] moveStringDownTwoSpaces(char[] s){
for(int j = 0; j < s.length; j++){
for(int i = s.length-3; i > j; i--){
s[i+2] = s[i];
}
return s;
}
}
I know this is O(n^2), but I don't quite understand the math behind transforming this:
(n -1) + (n - 2) + (n - 3) ... (n - n)
into this
O(n^2)
In my mind if n = 5 (String is of length 5), I would have...
(5-1) + (5-2) + (5-3) + (5-4) + (5-5) = 5(5 - ???)
which is
(n-1) + (n-2) + (n-3) + (n-4) + (n-5) = n(n - ???)
so that gives me 5*5 = 25 which is n^2. but what is the ??? I don't know what to put for the variables in the formula. I don't even know if I'm even going by this the correct way. AKA I forgot how to do math :(
(n -1) + (n - 2) + (n - 3) ... (n - n)
Just rewrite the following as:
1 + 2 + 3 + ....+ (n-1)
which is equal to: (n(n+1)/2 - n).
Now you can see it is O(n^2).
As noted by #hvd you may want to put the return statement outside the loop.
The Big-O notation is not the exact upper bound. It's an asymptotic upper bound. In many cases where a algorithm may look like O(n^2), but amortized analysis may show a linear order complexity.

Java: How do I perform integer division that rounds towards -Infinity rather than 0?

(note: not the same as this other question since the OP never explicitly specified rounding towards 0 or -Infinity)
JLS 15.17.2 says that integer division rounds towards zero. If I want floor()-like behavior for positive divisors (I don't care about the behavior for negative divisors), what's the simplest way to achieve this that is numerically correct for all inputs?
int ifloor(int n, int d)
{
/* returns q such that n = d*q + r where 0 <= r < d
* for all integer n, d where d > 0
*
* d = 0 should have the same behavior as `n/d`
*
* nice-to-have behaviors for d < 0:
* option (a). same as above:
* returns q such that n = d*q + r where 0 <= r < -d
* option (b). rounds towards +infinity:
* returns q such that n = d*q + r where d < r <= 0
*/
}
long lfloor(long n, long d)
{
/* same behavior as ifloor, except for long integers */
}
(update: I want to have a solution both for int and long arithmetic.)
If you can use third-party libraries, Guava has this: IntMath.divide(int, int, RoundingMode.FLOOR) and LongMath.divide(int, int, RoundingMode.FLOOR). (Disclosure: I contribute to Guava.)
If you don't want to use a third-party library for this, you can still look at the implementation.
(I'm doing everything for longs since the answer for ints is the same, just substitute int for every long and Integer for every Long.)
You could just Math.floor a double division result, otherwise...
Original answer:
return n/d - ( ( n % d != 0 ) && ( (n<0) ^ (d<0) ) ? 1 : 0 );
Optimized answer:
public static long lfloordiv( long n, long d ) {
long q = n/d;
if( q*d == n ) return q;
return q - ((n^d) >>> (Long.SIZE-1));
}
(For completeness, using a BigDecimal with a ROUND_FLOOR rounding mode is also an option.)
New edit: Now I'm just trying to see how far it can be optimized for fun. Using Mark's answer the best I have so far is:
public static long lfloordiv2( long n, long d ){
if( d >= 0 ){
n = -n;
d = -d;
}
long tweak = (n >>> (Long.SIZE-1) ) - 1;
return (n + tweak) / d + tweak;
}
(Uses cheaper operations than the above, but slightly longer bytecode (29 vs. 26)).
There's a rather neat formula for this that works when n < 0 and d > 0: take the bitwise complement of n, do the division, and then take the bitwise complement of the result.
int ifloordiv(int n, int d)
{
if (n >= 0)
return n / d;
else
return ~(~n / d);
}
For the remainder, a similar construction works (compatible with ifloordiv in the sense that the usual invariant ifloordiv(n, d) * d + ifloormod(n, d) == n is satisfied) giving a result that's always in the range [0, d).
int ifloormod(int n, int d)
{
if (n >= 0)
return n % d;
else
return d + ~(~n % d);
}
For negative divisors, the formulas aren't quite so neat. Here are expanded versions of ifloordiv and ifloormod that follow your 'nice-to-have' behavior option (b) for negative divisors.
int ifloordiv(int n, int d)
{
if (d >= 0)
return n >= 0 ? n / d : ~(~n / d);
else
return n <= 0 ? n / d : (n - 1) / d - 1;
}
int ifloormod(int n, int d)
{
if (d >= 0)
return n >= 0 ? n % d : d + ~(~n % d);
else
return n <= 0 ? n % d : d + 1 + (n - 1) % d;
}
For d < 0, there's an unavoidable problem case when d == -1 and n is Integer.MIN_VALUE, since then the mathematical result overflows the type. In that case, the formula above returns the wrapped result, just as the usual Java division does. As far as I'm aware, this is the only corner case where we silently get 'wrong' results.
return BigDecimal.valueOf(n).divide(BigDecimal.valueOf(d), RoundingMode.FLOOR).longValue();

Categories

Resources