洛谷 P3746 [六省联考 2017] 组合数问题
题目求 \(\displaystyle \sum _ {i = 0} [x ^ {ik + r}] (1 + x) ^ {nk}\),定义多项式的循环卷积为两个多项式相乘后,把所有 \(x ^ i\) 的项合并到 \(x ^ {i \bmod k}\)。快速幂加速即可。
时间复杂度 \(\text O (k ^ 2 \log nk)\)。
#include<cstdio>
#include<vector>
using namespace std;
typedef vector<int> poly;
int k,r,mod;
long long n;
inline void add(int &x,long long y) {x=(x+y)%mod;}
poly operator*(poly a,poly b) {
poly c(k);
for(int i=0;i<k;i++)
for(int j=0;j<k;j++)
add(c[(i+j)%k],1ll*a[i]*b[j]);
return c;
}
int main() {
scanf("%lld%d%d%d",&n,&mod,&k,&r),n*=k;
poly f(k),g(k); f[0]=g[0]=1,add(g[1%k],1);
for(;n;n>>=1) {
if(n&1) f=f*g;
g=g*g;
}
printf("%d\n",f[r]);
return 0;
}

浙公网安备 33010602011771号