Solution
有两种解法。
法1:
直接上分治FFT,也就是CDQ分治+FFT。
具体做法是先递归左半边,算出左半边答案之后,将左半边贡献到右半边,然后递归右半边。
分治是一个log的,每次暴力计算贡献是( ext O(n^2))的,考虑用FFT优化计算贡献的过程。总复杂度变成( ext O(n{log_n}^2))。
需要注意:因为只算左半边对右半边的贡献,所以f数组右半边应置为0。
法2:
设 (F(x)=sumlimits_{i=0}^{infty}f[i]x^i),(G(x)=sumlimits_{i=0}^{infty}g[i]x^i),并补充(g[0]=0),有
[egin{align}
F(x)*G(x)&=sumlimits_{i=0}^infty sumlimits_{j=0}^infty f[i]g[j]cdot x^{i+j}\
&=sumlimits_{k=0}^infty sumlimits_{i=0}^k f[i]g[k-i]cdot x^k
&=sumlimits_{k=0}^infty sumlimits_{i=0}^{k-1} f[i]g[k-i]cdot x^k
end{align}
]
当k=0是有(sumlimits_{i=0}^{k-1} f[i]g[k-i]cdot x^k=0)
当k>0时有 (sumlimits_{i=0}^{k-1} f[i]g[k-i]cdot x^k=f[k]cdot x^k)
所以(F(x))与(F(x)*G(x))只差了一个常数项(f[0])
即 (F(x)=F(x)*G(x)+f[0]) (Rightarrow) (F(x)=frac{f[0]}{1-G(x)}=frac{1}{1-G(x)})
多项式求逆即可。
这次重写发现自己NTT又有几个地方记不太清了:
1.数组范围应该是2N向上取2的次幂,因为两个长度是N的多项式相乘有2N项
2.for循环模拟递归过程,要注意是每一层操作相同且独立,所以不要把算单位根放在枚举每段起始位置p的那一层for了,应该放到最里层。
3.根据实际情况(mod x的多少次方)判断长度。
4.辅助数组用完记得清空。