HDU 3037 Saving Beans (组合+Lucas定理+逆元+快速幂)

来源:互联网 发布:mac cr2批量转换成jpg 编辑:程序博客网 时间:2024/05/14 17:28

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3037


Lucas定理

A、B是非负整数,p是质数。A B写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]。
则组合数C(A,B)与C(a[n],b[n])*C(a[n-1],b[n-1])*...*C(a[0],b[0]) mod p同余

即:Lucas(n,m,p)=C(n%p,m%p)*Lucas(n/p,m/p,p) 



AC代码:

#include <iostream>#include <vector>#include <list>#include <deque>#include <queue>#include <iterator>#include <stack>#include <map>#include <set>#include <algorithm>#include <cctype>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <cmath>using namespace std;typedef long long LL;const int N=52;const LL II=29;const int INF=0x3f3f3f3f;const double PI=acos(-1.0);LL p,xh[100100];void www(){    xh[0]=1;    for(LL i=1;i<=p;i++)        xh[i]=xh[i-1]*i%p;}LL power(LL a,LL b){    LL ans=1;    a=a%p;    while(b)    {        if(b&1) ans=(ans*a)%p;        a=(a*a)%p;        b=b/2;    }    return ans;}LL love(LL n,LL m){    LL ans=1;    while(n&&m)    {        LL nn=n%p,mm=m%p;        if(nn<mm)            return 0;        ans=ans*xh[nn]*power(xh[mm]*xh[nn-mm]%p,p-2)%p;        n/=p;        m/=p;    }    return ans%p;}int main(){    LL n,m;    int T;    cin>>T;    while(T--)    {        scanf("%I64d%I64d%I64d",&n,&m,&p);        www();        printf("%I64d\n",love(n+m,n));    }    return 0;}/*21 2 52 1 56 4 5*/


原创粉丝点击