hdu3037——卢卡斯定理

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

卢卡斯定理模板——大组合数取模

#include<iostream>
#include<cstdio>
using namespace std;
long long t,n,m,p,s;
long long mi(long long a,long long k)
{
    long long s=1;
    while(k)
    {
        if(k&1)s=s*a%p;
        k>>=1;
        a=a*a%p;
    }
    return s;
}
long long getc(long long n,long long m)
{
    if(n<m)return 0;
    long long s1=1;
    long long s2=1;
    if(n-m<m)m=n-m;
    for(long long i=1,j=n;i<=m;j--,i++)
    {
        s1=s1*j%p;
        s2=s2*i%p;
    }
    return s1*mi(s2,p-2)%p;
}
long long lucas(long long n,long long m)
{
    if(!m)return 1;
    return lucas(n/p,m/p)*getc(n%p,m%p)%p;
}
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld%lld",&n,&m,&p);
        printf("%lld\n",lucas(n+m,n));
    }
    return 0;
}

#include<iostream>
#include<cstdio>
using namespace std;
long long t,n,m,p,s,js[100005]={1};
long long mi(long long a,long long k)
{
    long long s=1;
    while(k>0)
    {
        if(k&1)s=s*a%p;
        k>>=1;
        a=a*a%p;
    }
    return s;
}
long long getc(long long n,long long m)
{
    if(n<m)return 0;
    if(n-m<m)m=n-m;
    return js[n]*mi(js[m],p-2)%p*mi(js[n-m],p-2)%p;
}
long long lucas(long long n,long long m)
{
    if(!m)return 1;
    return lucas(n/p,m/p)*getc(n%p,m%p)%p;
}
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld%lld",&n,&m,&p);
        for(int i=1;i<=p;i++)
            js[i]=js[i-1]*i%p;
        printf("%lld\n",lucas(n+m,n));
    }
    return 0;
}

 

posted on 2018-01-12 16:54  Narh  阅读(103)  评论(0编辑  收藏  举报

导航