【BZOJ 2982】 2982: combination (卢卡斯定理)
2982: combination
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 510 Solved: 316Description
LMZ有n个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样。那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案mod 10007的值。(1<=m<=n<=200,000,000)Input
第一行一个整数t,表示有t组数据。(t<=200)接下来t行每行两个整数n, m,如题意。Output
T行,每行一个数,为C(n, m) mod 10007的答案。Sample Input
4
5 1
5 2
7 3
4 2
Sample Output
5
10
35
6HINT
Source
【分析】
卢卡斯定理裸题。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define LL long long 8 #define Maxn 11000 9 const int Mod=10007; 10 11 int pw[Maxn],inv[Maxn]; 12 13 void init() 14 { 15 pw[0]=1;for(int i=1;i<=Mod;i++) pw[i]=1LL*pw[i-1]*i%Mod; 16 inv[1]=1;for(int i=2;i<=Mod;i++) inv[i]=1LL*(Mod-Mod/i)*inv[Mod%i]%Mod; 17 inv[0]=1;for(int i=1;i<=Mod;i++) inv[i]=1LL*inv[i-1]*inv[i]%Mod; 18 } 19 20 int get_c(int n,int m) 21 { 22 if(n<m) return 0; 23 return 1LL*pw[n]*inv[n-m]%Mod*inv[m]%Mod; 24 } 25 26 int lucas(int n,int m) 27 { 28 if(n<m) return 0; 29 int ans=1; 30 while(n&&m) 31 { 32 ans=1LL*ans*get_c(n%Mod,m%Mod)%Mod; 33 n/=Mod;m/=Mod; 34 } 35 return ans; 36 } 37 38 int main() 39 { 40 int T; 41 scanf("%d",&T); 42 init(); 43 while(T--) 44 { 45 int n,m; 46 scanf("%d%d",&n,&m); 47 printf("%d\n",lucas(n,m)); 48 } 49 return 0; 50 }
2017-04-16 16:27:16