题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6114
分析:手推了下发现就是对应在一串n个方格上取m个车放(n>m),然后看下横着放和竖着放都一样的。所以就是C(n,m)
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const LL p = 1e9+7;
LL sum = 0;
LL n,m;
LL pow_mod(LL a,LL b,LL p) {
LL sum=1;
while(b) {
if(b&1)
sum=(long long)sum*a%p;
a=(long long)a*a%p;
b>>=1;
}
return sum;
}
LL f(LL n,LL m,LL p) {
if(n<m) return 0;
if(m>n-m) m=n-m;
LL sum=1;
for(LL i=1;i<=m;i++) {
sum=(long long)sum*(n-i+1)%p;
LL a=pow_mod(i,p-2,p);
sum=(long long)sum*a%p;
}
return sum;
}
LL Lucas(LL n,LL m,LL p) {
if(m==0) return 1;
LL sum=1;
while(n&&m&&sum) {
sum=(long long)sum*f(n%p,m%p,p)%p;
n/=p;
m/=p;
}
return sum;
}
int main() {
LL T;
while(scanf("%I64d",&T) !=EOF) {
while(T--) {
scanf("%I64d%I64d",&n,&m);
if(n > m) swap(n,m);
printf("%I64d\n",Lucas(m,n,p));
}
}
return 0;
}