Remember the combination of the first few chapters.
We learned O (n^2) approach, plus the inverse, and we'll have an O (n) approach
Now comes the new question, if N and M are big,
For example, C (n, m)% p, n<=1e18,m<=1e18,p<=1e5
See no, N and M so big, but P is very small, we have to use this P
(number theory is such a boring thing, if I let n=1e100,m=1e100,p=1e100 you have the ability to calculate for me ah (°-°), not the same as not to be counted)
Then our famous Lucas (Lucas) stood out in the crowd (' Д?´) and said, "Let Lai teach you this question."
Lucas says:
C (n, m)% P = C (n/p, m/p) * C (n%p, m%p)% p
For C (n/p, m/p), if the n/p is still very large, you can recursively go down to the end of the world
The people heard this remark, all Marvel, wonderful! Wonderful!
(Laughing at Me O (* ≧▽≦) ツ┏━┓ the table laughs)
(Don't ask me to prove the process, I don't charge (´@@facesymbol@@ '))
And then on the code
1 int p) {2 return1; 3 }
Simple to understand < ( ̄︶ ̄) >
Try it.
HDU 5446
http://acm.hdu.edu.cn/showproblem.php?pid=5446
Test instructions
Here you are. Three numbers n, M, K
The second line is the number of K, p1,p2,p3...pk
All P values are not the same and p are prime numbers
The value of C (n, m)% (P1*P2*P3*...*PK)
range: 1≤m≤n≤1e, < Span id= "mathjax-span-32" class= "Mo" > < Span id= "mathjax-span-37" class= "Texatom" > 1 ≤k ≤10, < Span class= "mn" >pi≤1e5, guaranteed p1*p2*p3*...*pk≤1e
AC Code:
1#include <cstdio>2typedefLong LongLL;3 Const intN =100000+5;4LL Mul (ll A, ll B, ll P) {//fast multiply, calculate a*b%p5LL ret =0;6 while(b) {7 if(B &1) ret = (ret + a)%p;8A = (a + a)%p;9b >>=1;Ten } One returnret; A } -LL Fact (intN, LL p) {//the factorial of N to find remainder p -LL ret =1; the for(inti =1; I <= N; i + +) ret = ret * I%p; - returnret; - } - voidEX_GCD (ll A, ll B, LL &x, LL &y, LL &d) { + if(!B) {d = a, x =1, y =0;} - Else{ +EX_GCD (b, a%b, y, X, d); AY-= x * (A/b); at } - } -LL INV (ll T, ll P) {//if not present, return-1 - LL D, x, y; - ex_gcd (t, p, X, y, d); - returnD = =1? (x% p + p)% p:-1; in } -LL Comb (intNintM, LL p) {//C (n, m)% p to if(M <0|| M > N)return 0; + returnFact (n, p) * INV (Fact (M, p), p)% P * INV (FACT (N-M, p), p)%p; - } thell Lucas (ll N, ll M,intp) { * returnM? Lucas (n/p, m/p, p) * Comb (n%p, m%p, p)% p:1; $ }Panax NotoginsengLL China (intN, ll *a, ll *m) {//Chinese remainder theorem -LL M =1, ret =0; the for(inti =0; I < n; i + +) M *=M[i]; + for(inti =0; I < n; i + +){ ALL w = M/M[i]; the //ret = (ret + w * INV (W, m[i]) * a[i])% m;//This sentence will WA, use the following sentence +RET = (ret + mul (w * INV (W, M[i]), A[i], m))%M; - //because the direct multiply will explode long long, so I use fast multiply (unsigned long long is also burst, unless with high precision) $ } $ return(ret + M)%M; - } - intMain () { the intT, K; -LL N, M, p[ the], r[ the];Wuyiscanf"%d", &T); the while(t--){ -scanf"%i64d%i64d%d", &n, &m, &k); Wu for(inti =0; I < K; i + +){ -scanf"%i64d", &p[i]); AboutR[i] =Lucas (n, M, P[i]); $ } -printf"%i64d\n", China (K, R, p)); - } -}
View Code
It's all a routine ...
ACM NUMBER theory Tour---large combination-Lucas theorem (next Lucas, are you my master?) (。 -' ω´-))