求組合數
阿新 • • 發佈:2020-07-23
求組合數
1e4個詢問 2e3以內 p 遞推C[N] [N]
void init() {
for(int i=0;i<N;i++)
for(int j=0;j<=i;j++)
if(!j) c[i][j]=1;
else c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
1e4個詢問 1e5以內 p 預處理階乘和階乘的逆元
fact[0] = infact[0] = 1; for(int i = 1; i <= N; i ++) { fact[i] = (LL)fact[i - 1] * i % mod; infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod; } cin>>a>>b; cout<<(LL)fact[a] * infact[b] % mod * infact[a - b] % mod<<endl;
20個詢問 1e18以內 p是1e5以內 盧卡斯定理
int C(int a,int b) { if (b > a) return 0; int res=1; for(int i=1,j=a;i<=b;i++,j--) { res = (LL)res*j%p; res = (LL)res*qmi(i, p-2)%p; } return res; } int lucas(LL a, LL b) { if(a<p&&b<p) return C(a,b); return (LL)C(a % p, b % p) * lucas(a / p, b / p) % p; } cin>>a>>b>>p; cout<<lucas(a,b)<<endl;
輸入a和b 5000以內 不進行取模 分解質因數後進行高精度乘法
bool st[N]; int primes[N]; int cnt; int sum[N]; int a,b; cin>>a>>b; get_primes(N); for(int i=0;i<cnt;i++) { int p = primes[i]; sum[i] = primedivide3(a,p)-primedivide3(b,p)-primedivide3(a-b,p); } vector<int> res; res.push_back(1); for(int i=0;i<cnt;i++) for(int j=0;j<sum[i];j++) res = mul(res, primes[i]); //高精度乘法 for(int i=res.size()-1;i>=0;i--) cout<<res[i];