标签: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
分析:C(n,m)直接套用lucas定理和逆元的裸题
Code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,a,b) for(int i=a;i>=b;i--) #define mem(x,num) memset(x,num,sizeof x) #define LL long long using namespace std; inline LL read() { LL f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int p=10007; int fac[p],inv[p],n,m,T; void work() { fac[0]=fac[1]=inv[0]=inv[1]=1; rep(i,2,p-1)fac[i]=fac[i-1]*i%p; rep(i,2,p-1)inv[i]=(p-p/i)*inv[p%i]%p; rep(i,1,p-1)inv[i]=inv[i-1]*inv[i]%p; } int C(int n,int m) { if(n<m)return 0; if(n<p&&m<p)return fac[n]*inv[m]%p*inv[n-m]%p; return C(n/p,m/p)*C(n%p,m%p)%p; } int main() { work(); T=read(); while(T--) { n=read(),m=read(); printf("%d\n",C(n,m)); } return 0; }