D e s c r i p t i o n Description Description
计算组合数
I n p u t Input Input
第一行为一个整数T (1 <= T <= 10),表示测试数据组数。
接下来T行,每行有两个数,分别为n和m。
O u t p u t Output Output
对于每一对n和m,输出C(n, m)的值。每组数据各占一行。
S a m p l e Sample Sample I n p u t Input Input
2
4 2
5 3
S a m p l e Sample Sample O u t p u t Output Output
6
10
T r a i n Train Train o f of of T h o u g h t Thought Thought
直接暴力
高精压位
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ull unsigned long long
#define INF 10000
using namespace std;
ull n, m, l, ll, r, rr, Ans;
ull A[INF + 250];
int T;
void Mud(ull x, ull y, ull &z)
{
A[INF] = 1;
for(ull i = x + 1; i <= y; ++i)
{
ull t = i;
while(z && !(i % z))t /= z--;
ull g = 0;
for(int j =INF; j >= 1; j--)
{
A[j] = A[j] * t + g;
g = A[j] / (ull)1e9;
A[j] %= (ull)1e9;
}
}
}
void Div(ull k)
{
for(ull i = 2; i <= k; i++)
{
ull g = 0, h = 0, t = 1;
while(t <= INF && !A[t])
t++;t--;
while(++t && t <= INF)
{
A[t] += g;
g = (A[t] % i) * (ull)1e9;
A[t] /= i;
}
}
}
int main()
{
scanf("%d", &T);
while(T--)
{
memset(A, 0 ,sizeof(A));
scanf("%llu%llu", &n, &ll);
if((n - ll == (ull)1) || (ll == 1))
{printf("%llu\n", n);continue;}
if((n == ll) || !(ll))
{printf("1\n");continue;}
rr = n - ll;
l = max(ll, rr), r = min(ll, rr);
Mud(l, n, r);
Div(r);
int t = 1;
while(t <= INF && !A[t])
t++;
printf("%d", A[t]);
while(++t <= INF)
{
if(A[t] < 1e8)printf("0");
if(A[t] < 1e7)printf("0");
if(A[t] < 1e6)printf("0");
if(A[t] < 1e5)printf("0");
if(A[t] < 1e4)printf("0");
if(A[t] < 1e3)printf("0");
if(A[t] < 1e2)printf("0");
if(A[t] < 1e1)printf("0");
printf("%llu", A[t]);
}
printf("\n");
}
return 0;
}