组合数取模

1.n,m<=1000 p随意

   暴力

2.n,m<=10^6  p<=10^9 素数合数无影响

   分解质因数,然后快速幂 

   如果p是素数,且多次询问可以预处理阶乘的模以及阶乘的逆元

3.n,m<=10^9  p<=10^5且是质数

   lucas定理  多次询问也可以预处理

4.n,m<=10^9  p<=10^5且是合数

   目前还不会做系列。。。

   我们把p拆成 pi^ci 然后对每个pi求模,最后CRT(中国剩余定理)合并一下。

   考虑如何求这个。

   其实我们只要考虑n!mod p^c即可

   然后我们发现:

    n! = [ 1 * 2 * 4 * 5 * 7 * 8 * …  * 16 * 17 * 19 ] * (3 * 6 * 9 * 12 * 15 * 18)= [ 1 * 2 * 4 * 5 * 7 * 8 * …  * 16 * 17* 19 ] * 3^6( 1 * 2 * 3 * 4 * 5 * 6)

    把p单独处理之后发现前面是以p^c为周期的(显然),然后后面划归成了n/p,可以递归求解。然后p的次数就是n/p。

    这样我们就可以预处理阶乘,将是p的倍数的位数省略,以1代过。最后p快速幂一下就好。在分子上的话其实一样,只需要预处理成阶乘的逆元即可。

   说起来很麻烦,还是看代码比较好。。。

void divide(int n)
{
    for(int i=2;i*i<=n;i++)if(n%i==0)
    {
        p[++cnt]=i;pc[cnt]=1;
        while(n%i==0)pc[cnt]*=i,n/=i;
    }
    if(n>1)p[++cnt]=n,pc[cnt]=n;
}
inline ll power(ll x,ll y,ll p)
{
    ll t=1;
    for(;y;y>>=1,x=x*x%p)
        if(y&1)t=t*x%p;
    return t;
}
inline void exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b){x=1;y=0;return;}
    exgcd(b,a%b,x,y);
    ll t=x;x=y,y=t-a/b*y;
}
inline ll inv(ll a,ll b)
{
    ll x,y;
    exgcd(a,b,x,y);
    return (x%b+b)%b;
}
inline ll calc(ll n,ll p,ll pc)
{
    if(n<p)return fac[n];
    now+=n/p;
    return fac[n%pc]*power(fac[pc-1],n/pc,pc)%pc*calc(n/p,p,pc)%pc;
}
inline ll solve(ll p,ll pc)
{
    fac[0]=1;
    for1(i,pc-1)fac[i]=fac[i-1]*(i%p?i:1)%pc;
    now=0;
    ll t1=calc(n,p,pc),t2=1,cx=now,cy;
    for1(i,pc-1)fac[i]=fac[i-1]*(i%p?inv(i,pc):1)%pc;
    now=0;
    for1(i,m)t2=t2*calc(v[i],p,pc)%pc;
    cy=now;
    return t1*t2%pc*power(p,cx-cy,pc)%pc;
}    

int main()

{

    freopen("input.txt","r",stdin);

    freopen("output.txt","w",stdout);

    mod=read();n=read();m=read();
    for1(i,m)v[i]=read(),sum+=v[i];
    if(sum>n){printf("Impossible
");return 0;}
    if(sum<n)v[++m]=n-sum;
    divide(mod);
    ll ans=0;
    for1(i,cnt)
     {
         ll t1=solve(p[i],pc[i]),t2=inv(mod/pc[i],pc[i]);
         (ans+=t1*t2%mod*(mod/pc[i])%mod)%=mod;
     }
    cout<<(ans+mod)%mod<<endl;

    return 0;

}  

5.n,m<=10^9  p<=10^9

   目前无解决方法貌似?当然你要是和我说 pi^ci<=10^5 我就呵呵了。。。

  

原文地址:https://www.cnblogs.com/zyfzyf/p/4201833.html