求组合数
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];