This is a classical problem. Your job is to calculate the combination formula
C
(
n
,
m
)
, and
C
(
n
,
m
)
fit a 64-bit unsigned integer.(注意答案的范围)
The first line of input there is one integer
T
(
T
≤
100), giving the number of test cases in the input. Each test case contains a line with two integer n and m(0
≤
m
≤
n
<2
64
).
For each case, output
the answer
C
(
n
,
m
) corresponding to the input.
1 4 2
6
因为数据范围问题,所以min(n,n-m)中最小的一定小于两万
然后通过这个来计算组合数
注意里面的两个特判
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 20010
#define LL unsigned long long
LL gcd(LL a,LL b)
{
LL t;
while(b)
{
t=a%b;
a=b;
b=t;
}
return a;
}
LL demo[MAXN],nume[MAXN];
LL C(LL n,LL m)
{
if(n==m||m==0)
return 1;
if(m==n-1||m==1)
return n;
LL cnt1=0,cnt2=0,t,ans=1;
for(LL i=n-m+1;i<=n;++i)
nume[cnt1++]=i;
for(LL i=2;i<=m;++i)
demo[cnt2++]=i;
for(LL i=0;i<cnt2;++i){
for(LL j=0;demo[i]!=1&&j<cnt1;++j){
t=gcd(demo[i],nume[j]);
demo[i]/=t;
nume[j]/=t;
}
}
for(int i=0;i<cnt1;++i)
ans*=nume[i];
return ans;
}
int main()
{
int T;
LL n,m;
//freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%llu%llu",&n,&m);
m=min(m,n-m);
LL ans=C(n,m);
printf("%llu\n",ans);
}
return 0;
}