组合计数
排列数
long long A(long long m,long long n,long long mod){
long long ans=1;
for(long long i=n-m+1;i<=n;i++)
ans=ans*i%mod;
return ans;
}
时间复杂度 。
组合数
暴力
long long C(long long m,long long n,long long mod){
m=min(m,n-m);
long long ans=1;
for(long long i=n-m+1;i<=n;i++)
ans=ans*i;
for(int i=1;i<=m;i++)
ans/=i;
return ans;
}
时间复杂度 。
递推
通过递推求出 。
long long C[N][N];
void C_init(long long m,long long n,long long mod){
for(int i=1;i<=n;i++)
C[1][i]=i;
for(int i=2;i<=m;i++)
for(int j=i;j<=n;j++)
if(i^j)
C[i][j]=(C[i][j-1]+C[i-1][j-1])%mod;
else
C[i][j]=1;
}
预处理 ,查询 。
预处理阶乘及其逆元
同阶
预处理阶乘 及其逆元 ,通过公式求出组合数。
需要乘法逆元。
long long jc[N],jc_inv[N],mod;
void C_init(long long n){
jc[0]=jc[1]=1%mod;
for(long long i=2;i<=n;i++)
jc[i]=(jc[i-1]*i%mod);
for(long long i=1;i<=n;i++)
jc_inv[i]=qni_fm(jc[i],mod);
}
long long C(long long m,long long n){
return jc[n]*jc_inv[m]%mod*jc_inv[n-m]%mod;
}
预处理 ,查询 。
特小, 特大
需要乘法逆元。
long long inv[N],mod;
void C_init(int maxm){
for(int i=1;i<=maxm;i++)
inv[i]==qni_fm(i,mod);
}
long long C(long long m,long long n){
if(m<0||n<0||m>n)
return 0;
n%=mod;
if(!n||!m)
return 1;
long long ans=1;
for(int i=n;i>n-m;i--)
ans=ans*i%mod;
for(int i=1;i<=m;i++)
ans=ans*inv[i]%mod;
return ans;
}
预处理 ,查询 。
利用 定理
需要前面任何一种组合数求法 。
long long LC(long long m,long long n,long long mod){
if(!m)
return 1;
return LC(m/mod,n/mod,mod)*C(m%mod,n%mod,mod)%mod;
}
多重集的排列数
需要乘法逆元。
long long jc[N],jc_inv[N],mod;
void MA_init(long long n){
jc[0]=jc[1]=1%mod;
for(long long i=2;i<=n;i++)
jc[i]=(jc[i-1]*i%mod);
for(long long i=1;i<=n;i++)
jc_inv[i]=qni_fm(jc[i],mod);
}
long long MA(long long m,long long k,long long *n){
long long ans=jc[m];
for(int i=1;i<=k;i++)
ans=ans*jc_inv[n[i]]%mod;
return ans;
}
预处理 ,查询 。
多重集的组合数
需要前面 特小, 特大的预处理阶乘及其逆元的求组合数算法。
long long MC(int k,long long r,long long mod,long long *a){
long long ans=0,t;
int p;
C_init(K);
for(int x=0;x<(1<<k);x++)
if(!x)
ans=(ans+C(k-1,k+r-1))%mod;
else{
t=k+r;
p=0;
for(int i=0;i<k;i++)
if((x>>i)&1)
p++,t-=a[i+1];
t-=p+1;
ans=(ans+(p&1?-1:1)*C(k-1,t))%mod;
}
return (ans+mod)%mod;
}
时间复杂度 。
Catalan 数列
long long Catalan(long long n,long long mod){
return C(n,2*n,mod)*qni_fm(n+1,mod);
}

浙公网安备 33010602011771号