BZOJ 2982: combination Lucas定理

来源:互联网 发布:js农历日历控件 编辑:程序博客网 时间:2024/05/26 22:10

2982: combination

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 522  Solved: 321
[Submit][Status][Discuss]

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


这个题呢

显然是要用Lucas定理滴

C(n,m)=C(n%p,m%p)*C(n/p,m/p) mod p

当然,最重要的是题目本身的含义,不要多想


#include<cmath>#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<queue>#include<set>#include<map>using namespace std;typedef long long ll;inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return f*x;}const ll mod=10007;ll fac[mod<<1],inv[mod<<1];void initial(){fac[1]=1;inv[1]=1;inv[0]=1;for(int i=2;i<mod;i++)fac[i]=fac[i-1]*i%mod;for(int i=2;i<mod;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod;for(int i=1;i<mod;i++)inv[i]=inv[i-1]*inv[i]%mod;}ll Lucas(ll n,ll m){if(m>n)return 0;if(n<mod&&m<mod)return fac[n]*inv[n-m]*inv[m]%mod;else return Lucas(n%mod,m%mod)*Lucas(n/mod,m/mod)%mod;}int main(){int T=read();initial();while(T--){ll n=read(),m=read();printf("%lld\n",Lucas(n,m));}return 0;} 


0 1