今天学了一天数学,觉得自己都要转竞了23333
题目链接https://vjudge.net/contest/282927#problem/E
这里说一说求组合数的方法吧
其实就是求阶乘及其逆元的方法:
规定mod为模数,n为数据规模
1.mod为素数
费马小定理:nlogn
线性求逆元(n较小)
2.mod不为素数
欧拉筛出两个阶乘的素数,再计算出每个素数的次幂,最后快速幂乘起来即可
详见
n = read(),p = read();
ans = 1;
for(int i = 2;i <= 2 * n;i++)
{
if(isprime[i] == 0) prime[++tot] = i,minm[i] = i;
for(int j = 1;j <= tot && prime[j] * i <= 2 * n;j++)
{
isprime[i * prime[j]] = 1;
minm[i * prime[j]] = prime[j];
if(i % prime[j] == 0) break;
}
}
for(int i = n + 2;i <= 2 * n;i++) cnt[i] = 1;
for(int i = 1;i <= n;i++) cnt[i] = -1;
for(int i = 2 * n;i > 1;i--)
{
if(isprime[i])
{
cnt[minm[i]] += cnt[i];
cnt[i / minm[i]] += cnt[i];
}
}
for(int i = 2;i <= 2 * n;i++)
if(isprime[i] == 0)
ans = ans * power(i,cnt[i]) % p;
printf("%lld",ans);
数学使人憔悴啊qaq