最近做了不少的组合数的题
这里简单总结一下下

1.n,m很大p很小 且p为素数
p要1e7以下的 可以接受On的时间和空间
然后预处理阶乘 Lucas定理来做
以下是代码

/*Hdu3037 Saving Beans*/
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
#define maxn 1000010
using namespace std;
ll T,n,m,p,f[maxn];
void Get(){
    f[0]=1;
    for(int i=1;i<=p;i++)
        f[i]=f[i-1]*i%p;
}
ll qm(ll a,ll b){
    a%=p;ll r=1;
    while(b){
        if(b&1)r=r*a%p;
        b>>=1;a=a*a%p;
    }
    return r;
}
ll C(ll a,ll b){
    if(b>a)return 0;
    return f[a]*qm(f[b]*f[a-b],p-2)%p;
}
ll Lcs(ll a,ll b){
    if(b==0)return 1;
    return C(a%p,b%p)*Lcs(a/p,b/p)%p;
}
int main(){
    cin>>T;
    while(T--){
        cin>>n>>m>>p;Get();
        cout<<Lcs(n+m,n)<<endl;
    }
    return 0;
}
View Code

相关文章: