线性递推
bostan-mori
假设答案的 ogf 是 \(F(x)\),若 \(F(x)=\frac{P(x)}{Q(x)}\),对 \(Q(x)F(x)=P(x)\) 两边提取 \([x^n]\) 发现是个线性递推。
现在来直接计算 \([x^n]\frac{P(x)}{Q(x)}\),上下同乘 \(Q(-x)\) 得到 \(\frac{P(x)Q(-x)}{Q(x)Q(-x)}\),这时分母的奇数项都变成 0 了,那么算除法的时候分子的奇数项和偶数项之间就独立了。
假如 \(n\) 是奇数,那么分子只有奇数项有用,于是可以看成求 \([x^n]=\frac{xU(x^2)}{V(x^2)}=[x^{\frac{n-1}{2}}]\frac{U(x)}{V(x)}\),这里 \(U(x)\) 就是 \(P(x)Q(-x)\) 只把奇数项取出来然后从 \(0\) 往后排得到的多项式。偶数项的递归也是类似的。
只会递归 \(\log\) 次,那么这个算法的复杂度就是 \(\mathcal{O}(k\log k\log n)\) 的。
//[x^n]p(x)/q(x)
auto adjust=[&](Poly &f,int o){
int i;
for(i=o;i<(int)f.size();i+=2)
f[i/2]=f[i];
f.resize(i/2);
};
while(n){
int o=(n&1);n>>=1;
Poly rq=q;
for(int i=1;i<(int)rq.size();i+=2)rq[i]=del(0,rq[i]);
q=q*rq;
adjust(q,0);
p=p*rq;
if(!o)adjust(p,0);
else adjust(p,1);
}
if(p.size())cout<<1ll*p[0]*qpow(q[0],mod-2)%mod<<'\n';
else puts("0");