-2

Two integers n and k, both ranging in 100000 is given.

How do we calculate the LCM for n*n-1C0(multiplication of n and (n-1 choose 0)), n*n-1C1(multiplication of n and (n-1 choose 1)), n*n-1C2(multiplication of n and (n-1 choose 2)), .........., n*n-1Ck(multiplication of n and (n-1 choose k)) in modulo 1000000007.

I am simply finding all values and then calculating the modulo which have lot of problems when the numbers grows up.

How to calculate it efficiently ?

MetaD
  • 87
  • 1
  • 8

1 Answers1

3

Some ideas:

  1. It's easy to see that lcm(nx, ny) = n*lcm(x, y) So actually the problem reduced to calculating lcm for C coefficients.

  2. Also it is easy to see that lcm(x/a, x/b) = x/gcd(a, b), where gcd is a greatest common divisor.

If you remember that n choose k = n!/k!(n-k)! these two steps reduces the problem to calculation of

gcd(0!n!, 1!(n-1)!, 2!(n-2)!, ..., k!(n-k)!)

and then dividing n*n! by this value.

gcd can be easily computed by Euclidean algorithm. There's actually even easier approach:

gcd(i!(n-i)!, (i+1)!(n-i-1)!) = i!(n-i-1)!gcd(n-i, i+1)

(for the last gcd you still have to use Euclidean algorithm. but now it is easier).

  1. You can actually do all of the computations in a ring modulo 1000000007. It means that you can take a remainder of 1000000007 after each multiplication/addition, it wouldn't affect the answer.

  2. In the end you have two values:

x = n*n! mod 1000000007

y = gcd(0!n!, 1!(n-1)!, 2!(n-2)!, ..., k!(n-k)!) mod 1000000007

Instead of dividing these numbers, you can multiply x by z, such that

z*y = 1 modulo 1000000007

You can read more about why this works in this article and how to find such z here.

  1. You have to use 64-bit integers, because even product of two 1000000007-mod numbers doesn't fit into 32 bits. Alternatively, you can write your own mod-multiplication algorithm, which doesn't overflow 32-bit values (it is easy to do, if you know how to write multiplication algorithm and take my advice on calculation 1000000007 remainder after each step).
Roman Dobrovenskii
  • 935
  • 10
  • 23
  • To find the `z` value such that `x*z=1` you can just do a modular exponentiation of `x` to the power `1000000007-1-1` – fjardon Oct 07 '15 at 15:22
  • Yeah, it'd work, but there's a better approach: use Euclidean algorithm again. I added a link to the explaination. – Roman Dobrovenskii Oct 07 '15 at 15:30
  • For finding gcd(0!n!, 1!(n-1)!, 2!(n-2)!, ..., k!(n-k)!), we will be calculating gcd of numbers pairwise by the relation gcd(i!(n-i)!, (i+1)!(n-i-1)!) = i!(n-i-1)!gcd(n-i, i+1) and then calculating gcd for all those answers. Correct me if I am wrong ? – MetaD Oct 07 '15 at 15:59
  • MetaD, yes, this should work. – Roman Dobrovenskii Oct 07 '15 at 22:09