I've been trying to solve this problem:
Find Euler's totient function of binomial coefficient C(n, m) = n! / (m! (n - m)!) modulo 10^9 + 7, m <= n < 2 * 10^5.
One of my ideas was that first, we can precalculate the values of phi(i) for all i from 1 to n in linear time, also we can calculate all inverses to numbers from 1 to n modulo 10^9 + 7 using, for example, Fermat's little theorem. After that, we know, that, in general, phi(m * n) = phi(m) * phi(n) * (d / fi(d)), d = gcd(m, n). Because we know that gcd((x - 1)!, x) = 1, if x is prime, 2 if x = 4, and x in all other cases, we can calculate phi(x!) modulo 10^9 + 7 in linear time. However, in the last step, we need to calculate phi(n! / ((m! (n - m)!), (if we already know the function for factorials), so, if we are using this method, we have to know gcd(C(n, m), m! (n - m)!), and I don't know how to find it.
I've also been thinking about factorizing the binomial coefficient, but there seems no efficient way to do this.
Any help would be appreciated.
First, factorize all numbers 1..(2*10^5) as products of prime powers.
Now, factorize n!/k! = n(n-1)(n-2)...(n-k+1) as a product of prime powers by multiplying together the factors of the individual parts. Factorize (n-k)! as a product of prime powers. Subtract the latter powers from the former (to account for the divide).
Now you've got C(n, k) as a product of prime powers. Use the formula phi(N) = N * prod(1 - 1/p for p|N) to calculate phi(C(n, k)), which is straightforward given that you've computed the a list of all the prime powers that divide C(n, k) in the second step.
For example:
phi(C(9, 4)) = 9*8*7*6*5 / 5*4*3*2*1
9*8*7*6*5 = 3*3 * 2*2*2 * 7 * 3*2 * 5 = 7*5*3^3*2^4
5*4*3*2*1 = 5 * 2*2 * 3 * 2 * 1 = 5*3*2^3
9*8*7*6*5/(5*4*3*2*1) = 7*3^2*2
phi(C(9, 4)) = 7*3^2*2 * (1 - 1/7) * (1 - 1/3) * (1 - 1/2) = 36
I've done it in integers rather than integers mod M, but it seems like you already know how division works in the modulo ring.
Related
I am working with a lower triangular matrix, the function below calculates a row index of such matrix. How can I optimize it in terms of execution time?
The triangular matrix can hold at most N (N + 1) / 2 nonzero elements (where N is the matrix dimension - N x N).
I have a set of numbers 0, 1, 2, ..., N (N + 1) / 2 - 1 and from those, I have to calculate the matrix row index.
My current solution:
inline
unsigned int calc_row(unsigned int i)
{
return static_cast<unsigned int>(floor(sqrt(static_cast<double>(0.25 + 2 * i)) - 0.5));
}
// example:
calc_row(0) == 0;
calc_row(1) == 1;
calc_row(2) == 1;
calc_row(3) == 2;
calc_row(4) == 2;
calc_row(5) == 2;
Question:
1) Do you think my current solution is performance friendly?
2) If not how can I optimize it (in terms of the function execution time)?
If You believe an alternate method to calculate the row index would perform better, I am fine with it. Unfortunately the lookup table is not an option in my case.
EDIT #1:
I just had an idea: Is there a way to make a template metaprogramming version of the lookup table? A way to generate the row number at a compile time could prove to be a significant optimization. The biggest unsigned int i would be around 10 million in my case.
EDIT #2:
I edited the entire question because it caused a major confusion. I am sorry about that.
EDIT #3:
calc_row() calculates the formula: (sqrt(1 + 8 * i) - 1) / 2 which is the solution for the quadratic equation x(x + 1) / 2 = i. Where i is row index.
The main idea for this solution lies in the fact that the linear index for a triangular matrix with diagonal can be calculated as: i (i + 1) / 2 + j. Where i is row index and j is column index.
Can someone give me an idea of an efficient algorithm for large n which perform O(log(n)) using recursive function not geometric summation formula.
You need to use the formula for sum of geometric progression: a^1 + a^2 + ... a^n = (a^(n+1) - 1) / (a - 1). Using exponentiation by squaring you can compute (a^(n+1) - 1) in O(log(n)). If M is prime dividing by (a - 1) is simply one more exponentiation - for any U coprime with a prime number p, U^(-1) (mod p) = U^(p-2) (mod p). You can prove this using Fermat's little theorem.
First of all, as you state M < 105, you know that all numbers will need at most 16 bits, so provided being just a little cautious, you should not be bothered by precision questions.
Next, as an(mod M) = (a(mod M))n(mod M), you can also say a<M<105
Next if you note un=a0+a1...an-1 (mod M), you can use the following recursions:
u2k = uk+akuk (mod M)
uk+1 = uk+ak (mod M)
u2k+1 = uk+1+ak+1uk (mod M) = uk+ak+a*akuk (mod M)
Given a number n, you will find about log2(n) numbers n, n/2, n/4, ..., 1 and using the above formulas, you can compute easily un/2i and an/2i knowing un/2i+1 and an/2i+1
This algorythm may not be trivial to write (specifically do not forget the mod M operation do make sure not to have overflows) because of different tests, but it is O(log2(n))
i have read section about The Extended Euclidean Algorithm & Modular Inverses,which states that it not only computes GCD(n,m) but also a and b such that a*n+b*b=1;
algorithm is described by by this way:
Write down n, m, and the two-vectors (1,0) and (0,1)
Divide the larger of the two numbers by the smaller - call this
quotient q
Subtract q times the smaller from the larger (ie reduce the larger
modulo the smaller)
(i have question here if we denote by q n/m,then n-q*m is not equal to 0?because q=n/m;(assume that n>m),so why it is necessary such kind of operation?
then 4 step
4.Subtract q times the vector corresponding to the smaller from the
vector corresponding to the larger
5.Repeat steps 2 through 4 until the result is zero
6.Publish the preceding result as gcd(n,m)
so my question for this problem also is how can i implement this steps in code?please help me,i dont know how start and from which point could i start to solve such problem,for clarify result ,it should look like this
An example of this algorithm is the following computation of 30^(-1)(mod 53);
53 30 (1,0) (0,1)
53-1*30=23 30 (1,0)-1*(0,1)=(1,-1) (0,1)
23 30-1*23=7 (1,-1) (0,1)-1*(1,-1)=(-1,2)
23-3*7=2 7 (1,-1)-3*(-1,2)=(4,-7) (-1,2)
2 7-3*2=1 (4,-7) (-1,2)-3*(4,7)=(-13,23)
2-2*1=0 1 (4,-7)-2*(-13,23)=(30,-53) (-13,23)
From this we see that gcd(30,53)=1 and, rearranging terms, we see that 1=-13*53+23*30,
so we conclude that 30^(-1)=23(mod 53).
The division is supposed to be integer division with truncation. The standard EA for gcd(a, b) with a <= b goes like this:
b = a * q0 + r0
a = r0 * q1 + r1
r0 = r1 * q2 + r2
...
r[N+1] = 0
Now rN is the desired GCD. Then you back-substitute:
r[N-1] = r[N] * q[N+1]
r[N-2] = r[N-1] * q[N] + r[N]
= (r[N] * q[N+1]) * q[N] + r[N]
= r[N] * (q[N+1] * q[N] + 1)
r[N-3] = r[N-2] * q[N-1] + r[N-1]
= ... <substitute> ...
Until you finally reach rN = m * a + n * b. The algorithm you describe keeps track of the backtracking data right away, so it's a bit more efficient.
If rN == gcd(a, b) == 1, then you have indeed found the multiplicative inverse of a modulo b, namely m: (a * m) % b == 1.
I have the compute the sum S = (a*x + b*y + c) % N. Yes it looks like a quadratic equation but it is not because the x and y have some properties and have to be calculated using some recurrence relations. Because the sum exceeds even the limits of unsigned long long I want to know how could I compute that sum using the properties of the modulo operation, properties that allow the writing of the sum something like that(I say something because I do not remember exactly how are those properties): (a*x)%N + (b*y)%N + c%N, thus avoiding exceeding the limits of unsigned long long.
Thanks in advance for your concern! :)
a % N = x means that for some integers 0 <= x < N and m: m * N + x = a.
You can simply deduce then that if a % N = x and b % N = y then
(a + b) % N =
= (m * N + x + l * N + y) % N =
= ((m + l) * N + x + y) % N =
= (x + y) % N =
= (a % N + b % N) % N.
We know that 0 < x + y < 2N, that is why you need to keep remainder calculation. This shows that it is okay to split the summation and calculate the remainders separately and then add them, but don't forget to get the remainder for the sum.
For multiplication:
(a * b) % N =
= ((m * N + x) * (l * N + y)) % N =
= ((m * l + x * l + m * y) * N + x * y) % N =
= (x * y) % N =
= ((a % N) * (b % N)) % N.
Thus you can also do the same with products.
These properties can be simply derived in a more general setting using some abstract algebra (the remainders form a factor ring Z/nZ).
You can take the idea even further, if needed:
S = ( (a%N)*(x%N)+(b%N)*(y%N)+c%N )%N
You can apply the modulus to each term of the sum as you've suggested; but even so after summing them you must apply the modulus again to get your final result.
How about this:
int x = (7 + 7 + 7) % 10;
int y = (7 % 10 + 7 % 10 + 7 % 10) % 10;
You remember right. The equation you gave, where you %N every of the summands is correct. And that would be exactly what I use. You should also %N for every partial sum (and the total) again, as the addition results can be still greater than N. BUT be careful this works only if your size limit is at least twice as big as your N. If this is not the case, it can get really nasty.
Btw for the following %N operations of the partial sums, you dont have to perform a complete division, a check > N and if bigger just subtraction of N is enough.
Not only can you reduce all variable mod n before starting the calculation, you can write your own mod-mul to compute a*x mod n by using a shift-and-add method and reduce the result mod n at each step. That way your intermediate calculations will only require one more bit than n. Once these products are computed, you can add them pairwise and reduce mod n after each addition which will also not require more than 1 bit beyond the range of n.
There is a python implementation of modular multiplication in my answer to this question. Conversion to C should be trivial.
How can we computer (N choose K)% M in C or C++ without invoking overflow ?
For the particular case when N (4<=N<=1000) and K (1<=K<=N) and M = 1000003.
To compute (n choose k) % M, you can separately compute the nominator (n!) modulus M and the denominator (k!*(n - k)!) modulus M and then multiply the nominator by the denominator's modular multiplicative inverse (in M). Since M is prime, you can use Fermat's Little Theorem to calculate the multiplicative inverse.
There is a nice explanation, with sample code, on the following link (problem SuperSum):
http://www.topcoder.com/wiki/display/tc/SRM+467
Since 1000000003 = 23 * 307 * 141623 you can calculate (n choses k) mod 23, 307 and 141623 and then apply the chinese reminder theorem[1]. When calculating n!, k! and (n-k)!, you should calculate everythinng mod 23, 307 and 141623 each step to prevent overflow.
In this way you should avoid overflow even in 32bit machines.
A little improvement would be to calculate (n choses k) mod 141623 and 7061 (23 * 307) (edit: but it can be a little tricky to calculate the inverse modulus 7061, so I wouldn't do this)
I'm sorry for my poor English.
[1]http://en.wikipedia.org/wiki/Chinese_remainder_theorem
Edit2: Another potentially problem I've found is when calculating n! mod 23 (for example) it will probably be 0, but that doesn't implies that (n choses k) is 0 mod 23, so you should count how many times 23 divides n!, (n-k)! and k! before calculating (n choses k). Calculating this is easy, p divides n! exactly floor(n/p) + floor(n/p²) + ... times. If it happens that 23 divides n! the same times it divides k! and (n-k)!, the you proceed to calculate (n choses k) mod 23 dividing by 23 every multipler of it every time.The same applies for 307, but not for 141623
You could use the recursive formula from the link you gave and do the calculation mod M.
Here is a simple example:
(A * B * C) % N ... is equal to... ((A % N) * (B % N) * (C % N)) % N;
That is, all you need to apply modulus to every operand and product, or as soon as it becomes big a number. And last the modulus must apply to the overall result.
Use Stirling's approximation to calculate the binomial coefficient. Then just calculate the modulus as usual.