BZOJ2982
2982: combination
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 628 Solved: 379
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定理打上去完事。
代码如下:
#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;
const int p = 10007;
LL fpow(int a,int b){
LL res = 1;
while(b){
if(b&1)res = (res*a)%p;
a = (a*a)%p;
b >>= 1;
}
return res;
}
LL C(int m,int n){
LL res1 = 1,res2 = 1;
for(int i = 1;i <= n; i++)res1 = (res1*i)%p;
for(int j = m-n+1;j <= m; j++)res2 = (res2*j)%p;
return (res2*fpow(res1,p-2))%p;
}
LL lucas(int m,int n){
LL res = 1;
while(m && n){
LL mm = m%p,nn = n%p;
if(mm < nn)return 0;
res = (res*C(mm,nn))%p;
n /= p;
m /= p;
}
return res;
}
int main(){
int T,n,m;
scanf("%d",&T);
while(T--){
scanf("%d%d",&m,&n);
LL ans = lucas(m,n);
printf("%lld\n",ans%p);
}
return 0;
}