标签: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;
}