1067 - Combinations
Time Limit: 2 second(s) | Memory Limit: 32 MB |
Given n different objects, you want to take k of them. How many ways to can do it?
For example, say there are 4 items; you want to take 2 of them. So, you can do it 6 ways.
Take 1, 2
Take 1, 3
Take 1, 4
Take 2, 3
Take 2, 4
Take 3, 4
Input
Input starts with an integer T (≤ 2000), denoting the number of test cases.
Each test case contains two integers n (1 ≤ n ≤ 106), k (0 ≤ k ≤ n).
Output
For each case, output the case number and the desired value. Since the result can be very large, you have to print the result modulo 1000003.
Sample Input | Output for Sample Input |
3 4 2 5 0 6 4 | Case 1: 6 Case 2: 1 Case 3: 15 |
直接套用Lucas定理的公式就行了。具体见下一篇博客,写了个总结。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
LL mod = 1000003;
LL fac[1000000+11] = {1,1};
void getfac() //打一个阶乘表
{
for (int i = 2 ; i <= 1000000 ; i++)
fac[i] = fac[i-1] * i % mod;
}
LL quick(LL n , LL m) //求快速幂
{
LL ans = 1;
n %= mod;
while (m)
{
if (m & 1)
ans = ans * n % mod;
n = n * n % mod;
m >>= 1;
}
return ans;
}
LL C(LL n , LL k) //费马小定理求逆元
{
if (k > n)
return 0;
else
return fac[n] * (quick(fac[k] * fac[n-k] % mod , mod - 2)) % mod;
}
LL Lucas(LL n,LL k) //Lucas定理递归
{
if (k == 0) //递归终止条件
return 1;
else
return C(n % mod , k % mod) * Lucas(n / mod , k / mod) % mod;
}
int main()
{
getfac();
LL n,k;
int Case = 1;
int u;
scanf ("%d",&u);
while (u--)
{
scanf ("%lld %lld",&n,&k);
printf ("Case %d: %lld\n",Case++,Lucas(n,k));
}
return 0;
}