题目大意
格子的第一行及第一列均是给定的:
F[k,1]=lk
F[1,k]=tk
对于其他格子,满足递推式:
F[i,j]=a*F[i,j-1]+b*F[i-1,j]+c
求F[n,n](mod 1000003)。
解题思路
对于我们发现三项互不影响,使用组合数可以o(n)算出前两项,对于第三项我们可以得出贡献等于
∑N−2i=0∑N−2j=0Cii+jaibjc
通过拆开组合数可以变成卷积的形式,使用fft优化。
但是我们发现这是一个正方向,对角线上c的系数和可以乘以a+b得到下一条对角线的系数和,对于正方形的另一半每一次还要用组合数减去两个多出来的数。
code
using namespace std;
int const Mxn=2*1e5+9,Mo=1000003,Inf=1e9;
int N,PowA[Mxn],PowB[Mxn],Fact[Mxn*2],NFact[Mxn*2];
int c(int X,int Y){
return 1ll*Fact[X]*NFact[Y]%Mo*NFact[X-Y]%Mo;
}
int Pow(LL X,int Y){
LL Z=1;
while(Y){
if(Y&1)Z=Z*X%Mo;
X=X*X%Mo;
Y>>=1;
}
return Z;
}
int main(){
//freopen("matrix.in","r",stdin);
//freopen("matrix.out","w",stdout);
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
LL A,B,C;
Fact[0]=NFact[0]=Fact[1]=NFact[1]=1;
Fo(i,2,400000)Fact[i]=1ll*Fact[i-1]*i%Mo,NFact[i]=Pow(Fact[i],Mo-2);
while(scanf("%d%lld%lld%lld",&N,&A,&B,&C)!=EOF){
int Ans=0,X;PowA[0]=PowB[0]=1;
Fo(i,1,N)
PowA[i]=A*PowA[i-1]%Mo,PowB[i]=B*PowB[i-1]%Mo;
scanf("%d",&X);
Fo(i,2,N){
scanf("%d",&X);
Ans=(Ans+1ll*PowA[N-1]*PowB[N-i]%Mo*c(N*2-i-2,N-2)%Mo*X)%Mo;
}
scanf("%d",&X);
Fo(i,2,N){
scanf("%d",&X);
Ans=(Ans+1ll*PowA[N-i]*PowB[N-1]%Mo*c(N*2-i-2,N-2)%Mo*X)%Mo;
}
int Tmp=1,Ans2=1;
Fo(i,1,N-2)
Tmp=Tmp*(A+B)%Mo,Ans2=(Ans2+Tmp)%Mo;
Fo(i,0,N-3)
Tmp=(Tmp*(A+B)-1ll*(1ll*PowA[N-1]*PowB[i]%Mo+1ll*PowA[i]*PowB[N-1]%Mo)%Mo*c(N+i-2,N-2)%Mo)%Mo,Ans2=(Ans2+Tmp)%Mo;
Ans2=(Ans2+Mo)%Mo;
printf("%d\n",(Ans+Ans2*C)%Mo);
}
return 0;
}