题目
这个卡特兰数式的生成函数一看就可以用整式递推。
上模板。
本来想骚操作一波往模板里带入
的。
然后一直
,一度怀疑模板的正确率低下,后来才发现,原来我这波操作之后,
相当于数组被移位了。。。。。。所以整式递推的式子错误了。
所以带
就行了,如果不想带入
的话(比如这个题他没有说
几你也不好假定
几),你就在外面注意被移位了的处理即可。
#include<bits/stdc++.h>
#define maxn 10000007
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
#define St 13
#define LL long long
#define vc vector
#define vi vc<int>
#define Ct const
#define mod 1000000007
using namespace std;
int n,K,A,B,Q,f[maxn];
int Pow(int b,int k){ int r=1;for(;k;k>>=1,b=1ll*b*b%mod) if(k&1) r=1ll*r*b%mod; return r; }
vc<vi >PR(Ct vi&a,int D){
int N=a.size(),B=(N+2)/(D+2),C=(D+1)*B,R=N-(B-1),c=C,p;
vc<vi >b(R,vi(C));
rep(i,0,R-1) rep(j,0,B-1) for(int k=0,x=a[i+j];k<=D;k++,x=(LL)x*i%mod) b[i][j*(D+1)+k]=x;
rep(i,0,C-1){ rep(j,(p=-1,i),R-1) if(b[j][i]){p=j;break;}
if(p==-1){c=i;break;}swap(b[i],b[p]);
p=Pow(b[i][i],mod-2);rep(j,i,C-1) b[i][j]=(LL)b[i][j]*p%mod;
rep(j,i+1,R-1) if(p=b[j][i]) rep(k,i,C-1) b[j][k]=(b[j][k]-(LL)b[i][k]*p)%mod;
}assert(c^C);
per(i,c-1,0) if(b[i][c]) rep(j,0,i-1) b[j][c]=(b[j][c]-(LL)b[j][i]*b[i][c])%mod;
int M=c/(D+1)+1,S;
vc<vi >r(M,vi(D+1));
rep(i,(r[0][c%(D+1)]=1,0),c-1) r[M-i/(D+1)-1][i%(D+1)]=-b[i][c];
for(int i=0;i<M;i++) rep(j,0,D) rep(k,(S=(j+1ll)*(-M+1)%mod,j+1),D)
r[i][j]=(r[i][j]+(LL)S*r[i][k])%mod,S=S*(-M+1ll)%mod*(k+1)%mod*Pow(k-j+1,mod-2)%mod;
return r;
}
int cal(Ct vi&a,int x){ int r=0,s=1;rep(i,0,a.size()-1) r=(r+(LL)s*a[i])%mod,s=(LL)s*x%mod;return r; }
int val[maxn],pr[maxn],inv[maxn],sc;
int pan(int x){ x=(x%mod+mod)%mod;return x>(mod/2)?x-mod:x; }
int main(){
scanf("%d%d%d%d",&n,&f[1],&A,&B);
f[0]=3;
rep(i,2,St){ f[i] = (LL)f[i-1] * A % mod;
rep(j,1,i-1) f[i] = (f[i] + (LL)f[j] * f[i-j] % mod * B) % mod;}
vc<vi >r = PR(vi(f,f+St+1),1);
rep(i,St+(pr[St]=1),n) val[i]=cal(r[0],i),pr[i]=(LL)pr[i-1]*val[i]%mod;
sc=Pow(pr[n],mod-2);
per(i,n,St+1) inv[i]=(LL)sc*pr[i-1]%mod,sc=(LL)sc*val[i]%mod;
rep(i,St+1,n){
rep(j,1,r.size()-1) f[i]=(f[i]-(LL)f[i-j]*cal(r[j],i))%mod;
f[i]=(LL)f[i]*inv[i]%mod;
}
rep(i,1,n) f[i]=((LL)f[i]*f[i]+f[i-1])%mod;
scanf("%d",&Q);
for(int L,R;Q--;) scanf("%d%d",&L,&R),printf("%d\n",((f[R]-f[L-1])%mod+mod)%mod);
}