hrbeu 组合数 组合数对数取余

题目链接:http://acm.hrbeu.edu.cn/index.php?act=problem&id=1010&cid=25

其中P为非素数,所以有:

将C(n,m)%p=p0^C0```pi^Ci%p

#include<stdio.h>
#include<string.h>
#define LL long long
#define nmax 100001
int flag[nmax], prime[nmax];
int plen;
void mkprime() {
int i, j;
memset(flag, -1, sizeof(flag));
for (i = 2, plen = 0; i < nmax; i++) {
if (flag[i]) {
prime[plen++] = i;
}
for (j = 0; (j < plen) && (i * prime[j] < nmax); j++) {
flag[i * prime[j]] = 0;
if (i % prime[j] == 0) {
break;
}
}
}
}
int getMin(int a, int b) {
return a > b ? b : a;
}
int getNum(int n, int p) {
int res;
res = 0;
while (n) {
res += n / p;
n /= p;
}
return res;
}
int modular_exp(int a, int b, int c) {
LL res, temp;
res = 1 % c, temp = a % c;
while (b) {
if (b & 1) {
res = res * temp % c;
}
temp = temp * temp % c;
b >>= 1;
}
return (int) res;
}
void solve(int a, int b, int c) {
int i, temp;
LL res;
for (i = 0, res = 1; (i < plen) && (prime[i] <= a); i++) {
temp = getNum(a, prime[i]) - getNum(b, prime[i])
- getNum(a - b, prime[i]);
res = res * modular_exp(prime[i], temp, c) % c;
}
printf("%lld\n", res);
}

int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int t, a, b, c;
mkprime();
scanf("%d", &t);
while (t--) {
scanf("%d %d %d", &a, &b, &c);
solve(a + b, getMin(a, b), c);
}
return 0;
}

你可能感兴趣的:(组合)