Codechef JADUGAR2 Chef and Same Old Recurrence 2

Link
(f)的生成函数为(P(x))(下文简记为(P)),那么我们可以得到(P=AxP+BF^2+Kx)
解方程得到(P=frac{1-Axpmsqrt{A^2x^2-(2A+4KB)x+1}}{2B}),不妨令根号前的符号为负号,因此有(I_1:P=frac{1-Ax-sqrt{A^2x^2-(2A+4KB)x+1}}{2B})
(Q(x)=sqrt{A^2x^2-(2A+4KB)x+1})(下文简记为(Q)),变形得到(I_2:Q^2=A^2x^2-(2A+4KB)x+1)
(I_2)代入(I_1)得到(2BP=1-Ax-Q),移项得到(I_3:Q=1-Ax-2BP)
(I_3)求导得到(I_4:Q'=-A-2BP')
(I_2)求导得到(2QQ'=2A^2x-2A-4KB),化简得到(I_5:QQ'=A^2x-A-2KB)
(I_4)代入(I_5)得到((A+2BP')Q=A+2KB-A^2x),变形得到(I_6:(A+2BP')Q^2=(A+2KB-A^2x)Q)
(I_2,I_3)代入(I_6)得到(I_7:(A+2BP')(A^2x^2-(2A+4KB)x+1)=(A+2KB-A^2x)(1-Ax-2BP))
观察(x^n)的系数可以艰难地得到(nf_n=(2n-3)(A+2KB)f_{n-1}-(n-3)A^2f_{n-2})
然后递推求出每一项再做个平方的前缀和就可以(O(1))回答询问了。

#include<cstdio>
const int N=100000007,P=1000000007;
int read(){int x;scanf("%d",&x);return x;}
int inc(int a,int b){return a+=b-P,a+(a>>31&P);}
int dec(int a,int b){return a-=b,a+(a>>31&P);}
int mul(int a,int b){return 1ll*a*b%P;}
int f[N],inv[N];
int main()
{
    int n=read(),k=read(),a=read(),b=read(),p=inc(a,mul(2*k,b)),q=mul(a,a);
    inv[1]=1,f[1]=k,f[2]=mul(inc(a,mul(b,k)),k);
    for(int i=2;i<=n;++i) inv[i]=mul(inv[P%i],P-P/i);
    for(int i=3;i<=n;++i) f[i]=mul(inv[i],dec(mul(mul(2*i-3,p),f[i-1]),mul(mul(i-3,q),f[i-2])));
    for(int i=1;i<=n;++i) f[i]=inc(f[i-1],mul(f[i],f[i]));
    for(int Q=read(),l,r;Q;--Q) l=read(),r=read(),printf("%d
",dec(f[r],f[l-1]));
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12257804.html