数论——lucas定理

Posted blues

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论——lucas定理相关的知识,希望对你有一定的参考价值。

网上证明很多,虽然没看懂。。。。

主要解决大组合数取模的情况

百度之星2016 1003

先推公式,再lucas

p很大的情况 1e9+7

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cstdio>
 6 #include<set>
 7 #include<map>
 8 #include<vector>
 9 #include<cstring>
10 #include<stack>
11 #include<cmath>
12 #include<queue>
13 #define clc(a,b) memset(a,b,sizeof(a))
14 #include <bits/stdc++.h>
15 const int maxn = 20005;
16 const int inf=0x3f3f3f3f;
17 const double pi=acos(-1);
18 typedef long long LL;
19 using namespace std;
20 const LL MOD = 1e9+7;
21 
22 LL exp_mod(LL a, LL b, LL p)
23 {
24     LL res = 1;
25     while(b != 0)
26     {
27         if(b&1) res = (res * a) % p;
28         a = (a*a) % p;
29         b >>= 1;
30     }
31     return res;
32 }
33 
34 LL Comb(LL a, LL b, LL p)
35 {
36     if(a < b)   return 0;
37     if(a == b)  return 1;
38     if(b > a - b)   b = a - b;
39 
40     LL ans = 1, ca = 1, cb = 1;
41     for(LL i = 0; i < b; ++i)
42     {
43         ca = (ca * (a - i))%p;
44         cb = (cb * (b - i))%p;
45     }
46     ans = (ca*exp_mod(cb, p - 2, p)) % p;
47     return ans;
48 }
49 
50 LL Lucas(int n, int m, int p)
51 {
52     LL ans = 1;
53 
54     while(n&&m&&ans)
55     {
56         ans = (ans*Comb(n%p, m%p, p)) % p;
57         n /= p;
58         m /= p;
59     }
60     return ans;
61 }
62 
63 int main()
64 {
65     int n, m;
66     LL p;
67     while(~scanf("%d%d", &n, &m))
68     {
69         p=MOD;
70         printf("%I64d\n", Lucas(n+m-4, m-2, p));
71     }
72     return 0;
73 }

 

p在100000左右

HDU 3037

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cstdio>
 6 #include<set>
 7 #include<map>
 8 #include<vector>
 9 #include<cstring>
10 #include<stack>
11 #include<cmath>
12 #include<queue>
13 #define clc(a,b) memset(a,b,sizeof(a))
14 #include <bits/stdc++.h>
15 const int maxn = 20005;
16 const int inf=0x3f3f3f3f;
17 const double pi=acos(-1);
18 typedef long long LL;
19 using namespace std;
20 //const LL MOD = 1e9+7;
21 
22 LL PowMod(LL a,LL b,LL MOD){
23     LL ret=1;
24     while(b){
25         if(b&1) ret=(ret*a)%MOD;
26         a=(a*a)%MOD;
27         b>>=1;
28     }
29     return ret;
30 }
31 LL fac[100005];
32 LL Get_Fact(LL p){
33     fac[0]=1;
34     for(int i=1;i<=p;i++)
35         fac[i]=(fac[i-1]*i)%p;
36 }
37 LL Lucas(LL n,LL m,LL p){
38     LL ret=1;
39     while(n&&m){
40         LL a=n%p,b=m%p;
41         if(a<b) return 0;
42         ret=(ret*fac[a]*PowMod(fac[b]*fac[a-b]%p,p-2,p))%p;
43         n/=p;
44         m/=p;
45     }
46     return ret;
47 }
48 int main(){
49     int t;
50     scanf("%d",&t);
51     while(t--){
52         LL n,m,p;
53         scanf("%I64d%I64d%I64d",&n,&m,&p);
54         Get_Fact(p);
55         printf("%I64d\n",Lucas(n+m,m,p));
56     }
57     return 0;
58 }

 

以上是关于数论——lucas定理的主要内容,如果未能解决你的问题,请参考以下文章

Lucas定理--组合数取模

组合数取模&&Lucas定理题集

Lucas定理及组合数取模

HDU 3037 Saving Beans(Lucas定理的直接应用)

模版卢卡斯定理

大组合数取余模板Lucas定理