soj 3290 Distribute The Apples I 组合数对素数取余

由于素数P比较小,所以可以先打表,求出小于P的数的阶乘对与该素数的余数,这样节省了中间求阶乘的时间。

/*
* soj3290.c
*
* Created on: 2011-10-10
* Author: bjfuwangzhu
*/

#include<stdio.h>
#define LL long long
#define nmod 10009
int num[nmod];
void init() {
int i;
for (i = 1, num[0] = 1; i < nmod; i++) {
num[i] = num[i - 1] * i % nmod;
}
}
int modular_exp(int a, int b) {
int res, temp;
res = 1 % nmod,temp = a % nmod;
while (b) {
if (b & 1) {
res = res * temp % nmod;
}
temp = temp * temp % nmod;
b >>= 1;
}
return res;
}
int C(int a, int b) {
int res;
if (b > a) {
return 0;
}
b = num[b] * num[a - b] % nmod;
a = num[a];
res = modular_exp(b, nmod - 2);
res = res * a % nmod;
return res;
}
void solve(int n, int m) {
int a, b, res;
res = 1;
while (n || m) {
a = n % nmod,b = m % nmod;
res = res * C(a, b) % nmod;
n /= nmod,m /= nmod;
}
printf("%d\n", res);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int n, k;
LL temp;
init();
while (~scanf("%d %d", &n, &k)) {
temp = (LL) k;
temp = temp * (temp + 1) / 2;
if (temp > n) {
puts("0");
continue;
}
n = n - (int) temp;
solve(n + k - 1, n);
}
return 0;
}

 

若不是先打表求N!,则求组合数的函数又可以这么写:

int C(int a, int b) {
int i, resa, resb, res;
if (b > a) {
return 0;
}
for (i = 0, resa = 1, resb = 1; i < b; i++) {
resa = resa * (a - i) % nmod;
resb = resb * (b - i) % nmod;
}
res = modular_exp(resb, nmod - 2);
res = res * resa % nmod;
return res;
}



posted @ 2011-10-10 13:06  qingyezhu  阅读(195)  评论(0编辑  收藏  举报