1. 程式人生 > >bzoj2982: combination(Lucas定理)

bzoj2982: combination(Lucas定理)

Description

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
6
 
  $n,m$這麼大,$mod$這麼小 上個裸的$Lucas$ 解決。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4
#define re register 5 using namespace std; 6 int min(int a,int b){return a<b?a:b;} 7 const int p=1e4+7; 8 int t,n,m,fac[p+2]; 9 int Pow(int x,int y){ 10 int res=1; 11 for(;y;y>>=1,x=1ll*x*x%p) 12 if(y&1) res=1ll*res*x%p; 13 return res; 14 } 15 int C(int
a,int b){ 16 return a<b?0:1ll*fac[a]*Pow(fac[b],p-2)%p*Pow(fac[a-b],p-2)%p; 17 } 18 int lucas(int a,int b){ 19 return b?1ll*lucas(a/p,b/p)%p*C(a%p,b%p)%p:1; 20 } 21 int main(){ 22 scanf("%d",&t); fac[0]=1; 23 for(int i=1;i<=p;++i) fac[i]=1ll*fac[i-1]*i%p; 24 while(t--){ 25 scanf("%d%d",&n,&m); 26 printf("%d\n",lucas(n,min(m,n-m))); 27 }return 0; 28 }
View Code