zoukankan      html  css  js  c++  java
  • 大组合取模之:1<=n<=m<=1e6,1<=p<=1e9

    /******************************
     大组合取模之:1<=n<=m<=1e6,1<=p<=1e9
     使用:程序最开始调用getprime(),需要时调用C(n,m,p)
     复杂度:O( n*log(n) )
     ******************************/
    typedef long long ll;
    #define N 210000
    
    int PRIME[N/2];
    
    void getprime()
    {
        bool pmark[N+1000];
        memset(pmark,0,sizeof(pmark));
        int pcnt=0;
        PRIME[pcnt++]=2;
        for(int i=3;i<N+1000;i+=2)
        {
            if(pmark[i]==0)
            {
                PRIME[pcnt++]=i;
                for(int j=i;j<N+1000;j+=i) pmark[j]=1;
            }
        }
    }
    
    /**************
     快速幂模板
     调用:Quk_Mul(a,b,mod)
     返回:a^b%mod
     复杂度:当mod>10^9,log(mod)*log(b),否则log(b)
     ***************/
    long long Mod_Mul(long long a,long long b,long long mod)
    {
        long long msum=0;
        while(b)
        {
            if(b&1) msum = (msum+a)%mod;
            b>>=1;
            a = (a+a)%mod;
        }
        return msum;
    }
    
    long long Quk_Mul(long long a,long long b,long long mod)
    {
        bool qmflag=mod>1e9?1:0;
        long long qsum=1;
        while(b)
        {
            if(b&1) qsum = (qmflag==1) ? Mod_Mul(qsum,a,mod) : (qsum*a)%mod;
            b>>=1;
            a = (qmflag==1) ? Mod_Mul(a,a,mod) : (a*a)%mod;
        }
        return qsum;
    }
    
    // 得到n! 中有多少个d因子
    int getdn(int n,int d)
    {
        int sum=0;
        while(n)
        {
            sum += n/d;
            n/=d;
        }
        return sum;
    }
    
    ll C(int n,int m,ll p)
    {
        if(m>n) return 0;
        ll sumc=1;
        for(int i=0;PRIME[i]<=n;i++)
        {
            int cnum = getdn(n,PRIME[i])-getdn(m,PRIME[i])-getdn(n-m,PRIME[i]);
            sumc = sumc*Quk_Mul(PRIME[i], cnum, p)%p;
        }
        return sumc;
    }
    
    /*
    int main() {
        getprime();
        int T;
        cin>>T;
        while(T--)
        {
            int n,m,p;
            cin>>n>>m>>p;
            cout<<C(n,m,p)<<endl;
        }
        return 0;
    }
    */
  • 相关阅读:
    双六
    除法取模
    欧拉函数及费马小定理
    基础模运算
    Leeetcode--581. Shortest Unsorted Continuous Subarray
    Codeforces Round #541--1131F. Asya And Kittens(基础并查集)
    leetcode--200. Number of Islands
    leetcode--21. Merge Two Sorted Lists
    leetcode--155. Min Stack
    Codeforces Round #539--1113B
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5081310.html
Copyright © 2011-2022 走看看