bzoj2982: combination(Lucas定理)

Description

LMZn个不同的基友,他每天晚上要选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

 

posted @ 2018-11-04 23:28  kafuuchino  阅读(208)  评论(0编辑  收藏  举报