HDU 3037 aving Beans [LUCAS定理]

  求C(n+m,m)%p ,n和m很大,p是小于10^5的素数。

  LUCAS定理。

 1 #include <string.h>
 2 #include <stdio.h>
 3 typedef long long LL;
 4 int cas;
 5 LL n, m, p;
 6 LL fac[100005];
 7 LL powmod(LL a, LL b, LL p){
 8     LL ans = 1, tmp = a;
 9     for (; b; b >>= 1, tmp = tmp * tmp % p)
10         if (b&1) ans = ans * tmp % p;
11     return ans;
12 }
13 LL lucas(LL n, LL m, LL p){
14     LL ans = 1;
15     while (n&&m) {
16         LL a = n%p, b = m%p;
17         if (a < b) return 0;
18         ans = ans * fac[a] * powmod(fac[b]*fac[a-b]%p,p-2,p) % p;
19         n /= p, m /= p;
20     }
21     return ans;
22 }
23 void getfact(LL p){
24     fac[0]=1;
25     for (int i = 1; i <= p; i++)
26         fac[i] = fac[i-1] * i % p;
27 
28 }
29 int main(){
30     scanf("%d", &cas);
31     while (cas--) {
32         scanf("%I64d%I64d%I64d", &n, &m, &p);
33         getfact(p);
34         printf("%I64d\n", lucas(n+m, m, p));
35     }
36     return 0;
37 }
posted @ 2012-10-09 14:03  Burn_E  阅读(250)  评论(0编辑  收藏  举报