题目描述
菁菁堂有一块数字格,那是王解体最喜欢去的地方。
传说中,这条气势磅礴的数字格,有N行N列,每一个格子里均有一个数。
敢于挑战自己的王解体决定来挑战这道通过率为百分之九十九的题目。
格子的第一行及第一列均是给定的:
F[k,1]=l[k](k=1,2,3,…,N)
F[1,k]=t[k](k=1,2,3,…,N)
对于其他格子,满足递推式:
F[i,j]=a*F[i,j-1]+b*F[i-1,j]+c
不出所料,当王解体能得到 F[n,n](mod 1000003)时,通过率将达到百分之百。
机智法
容易知道只需要考虑常数c的影响。
一条斜线一条斜线的扫。
c的贡献和每次乘a+b。
过半后会超出两端,单独计算减去即可。
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int mo=1000003,maxn=400000+10;
int fac[maxn],inv[maxn],L[maxn],T[maxn],mia[maxn],mib[maxn];
int i,j,k,l,t,n,m,ans,sum,num,a,b,c;
int quicksortmi(int x,int y){
if (!y) return 1;
int t=quicksortmi(x,y/2);
t=(ll)t*t%mo;
if (y%2) t=(ll)t*x%mo;
return t;
}
int C(int n,int m){
if (n<m||m<0) return 0;
return (ll)fac[n]*inv[m]%mo*inv[n-m]%mo;
}
int main(){
freopen("matrix.in","r",stdin);freopen("matrix.out","w",stdout);
fac[0]=1;
fo(i,1,maxn-10) fac[i]=(ll)fac[i-1]*i%mo;
inv[maxn-10]=quicksortmi(fac[maxn-10],mo-2);
fd(i,maxn-11,0) inv[i]=(ll)inv[i+1]*(i+1)%mo;
while (scanf("%d%d%d%d",&n,&a,&b,&c)!=EOF){
if (n==1){
scanf("%d%d",&t,&t);
t%=mo;
printf("%d\n",t);
continue;
}
mia[0]=mib[0]=1;
fo(i,1,n){
mia[i]=(ll)mia[i-1]*a%mo;
mib[i]=(ll)mib[i-1]*b%mo;
}
ans=0;
fo(i,1,n){
scanf("%d",&t);
if (i==1) continue;
(ans+=(ll)C(n-2+n-i,n-i)*mia[n-1]%mo*mib[n-i]%mo*t%mo)%=mo;
}
fo(i,1,n){
scanf("%d",&t);
if (i==1) continue;
(ans+=(ll)C(n-2+n-i,n-i)*mia[n-i]%mo*mib[n-1]%mo*t%mo)%=mo;
}
sum=num=1;
fo(i,1,n-2){
num=(ll)num*(a+b)%mo;
(sum+=num)%=mo;
}
fo(i,1,n-2){
num=(ll)num*(a+b)%mo;
j=n-i+1;k=2;
//t=(ll)C(n-j+n-k,n-j)*mib[n-j]%mo*mia[n-k]%mo;
t=(ll)C(n-j+n-k,n-j)*mib[n-j]%mo*mia[n-k]%mo*a%mo;
(num-=t)%=mo;
j=2;k=n-i+1;
//t=(ll)C(n-j+n-k,n-j)*mib[n-j]%mo*mia[n-k]%mo;
t=(ll)C(n-j+n-k,n-j)*mib[n-j]%mo*mia[n-k]%mo*b%mo;
(num-=t)%=mo;
(sum+=num)%=mo;
}
(ans+=(ll)sum*c%mo)%=mo;
(ans+=mo)%=mo;
printf("%d\n",ans);
}
}
2670

被折叠的 条评论
为什么被折叠?



