Lucas' theorem

  233333, I originally wanted to write it myself, but halfway through the writing, I found that there was a place I couldn’t, so I went to learn it now. After Blue Queen, Baidu came to a very good blog, I thought it was simple and easy to understand, the template provided by the blogger It is also easy to remember, it is better to directly reprint qwq

  Click to get the original text

First, the Lucas theorem is given:

    There are non-negative integers A, B, and prime p, A and B are written in p base as: A=a[n]a[n-1]...a[0], B=b[n]b[n -1]...b[0].

Then the combination number C(A,B) and C(a[n],b[n])×C(a[n-1],b[n-1])×...×C(a[0] ,b[0]) mod p is congruent.

That is: Lucas(n,m,p)=C(n%p,m%p)×Lucas(n/p,m/p,p), especially, Lucas(x,0,p)=1.

    In fact, to put it bluntly, Lucas's theorem is to find the value of the combination number C(n, m) mod p (p is a prime number), that is (( n! /(nm)!)/m! ) mod p, and we

Also know that (a/b)mod p=a*b^(p-2)mod p (a little knowledge of inverse elements and Fermat's little theorem is used here), so we can take p in the process of calculating factorial mode, will not cause overflow. (It should be noted that the range of p handled by Lucas's theorem is roughly on the order of 10^5)

 

  See the following question: HDU3037

  Topic link: http://acm.hdu.edu.cn/showproblem.php?pid=3037

  The gist of the title: m seeds should be placed on n trees, how many methods are there, and the result will be modulo the prime number p.

  Analysis: m seeds can be divided into two parts: those placed on the tree and those not placed on the tree, we can imagine the n+1th tree, and think that those seeds that are not placed on the tree are placed on this imaginary tree , in this way, the question becomes how many options are there for m seeds placed on n trees. Equivalent to how many sets of non-negative integer solutions to the equation X1+X2+...+Xn+1=m, that is (X1+1)+(X2+1)+...+(Xn+1+1)=m How many positive integer solutions are there for +n+1. Baffle principle: (m+n+1) 1s, the number of solutions divided into n+1 parts==>C(n+m,n). It's obvious here, decisive Lucas.

  Code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #define ll long long
 4 using namespace std;
 5 const int maxn=150010;
 6 int t;
 7 ll n,m,p;
 8 ll jc[maxn];
 9 void work(ll mod)
10 {
11     jc[0]=1;
12     for(int i=1;i<=p;++i)
13         jc[i]=jc[i-1]*i%mod;
14 }
15 ll qpow(ll a,ll b)
16 {
17     ll ans=1;
18     while(b)
19     {
20         if(b&1)ans=(ans*a%p)%p;
21         a=(a*a)%p;
22         b>>=1;
23     }
24     return ans;
25 }
26 ll C(ll n,ll m)
27 {
28     if(m>n)return 0;
29     returnjc[n]*qpow(jc[m]*jc[nm]%p,p- 2 )%p; // Theorem, the inverse of a%p is equal to a^(p-2)%p 
30  }
 31  ll lucas(ll n,ll m)
 32  {
 33      if (m== 0 ) return  1 ; // c(n,0)=1; 
34      else  return (C(n%p,m%p)*lucas(n /p,m/p)%p)% p;
 35  }
 36  int main()
 37  {
 38      scanf( " %d " ,& t);
 39      while (t-- )
 40      {
 41         scanf("%lld%lld%lld",&n,&m,&p);
42         work(p);
43         printf("%lld\n",lucas(n+m,m));
44     }
45     return 0;
46 }
View Code

  For the case where p is relatively large, the factorial cannot be preprocessed and needs to be processed separately.

  Topic link: http://acm.fzu.edu.cn/problem.php?pid=2020

  The gist of the title: Find C(n, m) mod p. n,p are on the order of 10^9.

  Code:

 1 #include <iostream>  
 2 #include <string.h>  
 3 #include <stdio.h>  
 4   
 5 using namespace std;  
 6 typedef long long LL;  
 7   
 8 LL n,m,p;  
 9   
10 LL quick_mod(LL a, LL b)  
11 {  
12     LL ans = 1;  
13     a %= p;  
14     while(b)  
15     {  
16         if(b & 1)  
17         {  
18             ans = ans * a % p;  
19             b--;  
20         }  
21         b >>= 1;  
22         a = a * a % p;  
23     }  
24     return ans;  
25 }  
26   
27 LL C(LL n, LL m)  
28 {  
29     if(m > n) return 0;  
30     LL ans = 1;  
31     for(int i=1; i<=m; i++)  
32     {  
33         LL a = (n + i - m) % p;  
34         LL b = i % p;  
35         ans = ans * (a * quick_mod(b, p-2) % p) % p;  
36     }  
37     return ans;  
38 }  
39   
40 LL Lucas(LL n, LL m)  
41 {  
42     if(m == 0) return 1;  
43     return C(n % p, m % p) * Lucas(n / p, m / p) % p;  
44 }  
45   
46 int main()  
47 {  
48     int T;  
49     scanf("%d", &T);  
50     while(T--)  
51     {  
52         scanf("%I64d%I64d%I64d", &n, &m, &p);  
53         printf("%I64d\n", Lucas(n,m));  
54     }  
55     return 0;  
56 }  
View Code

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326573806&siteId=291194637