Search code examples
c++algorithmbinomial-coefficients

Find euler function of binomial coefficient


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.


Solution

  • 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.