/****************************** 大组合取模之: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; } */
时间: 2024-10-14 08:45:58