题意
给你一个 n × n n \times n n×n 矩阵的第一行和第一列,其余的数通过如下公式推出:
F [ i , j ] = a ∗ f [ i , j − 1 ] + b ∗ f [ i − 1 , j ] + c F[i,j]=a*f[i,j-1]+b*f[i-1,j]+c F[i,j]=a∗f[i,j−1]+b∗f[i−1,j]+c
求 f [ n ] [ n ] m o d ( 1 0 6 + 3 ) f[n][n] mod (10^6+3) f[n][n]mod(106+3) 的值。
数据范围
对于 100 % 100\% 100% 的数据,满足 2 ≤ n ≤ 200000 2\leq n\leq200000 2≤n≤200000,其余的数在 [ 0 , 1 0 6 ] [0,10^6] [0,106] 之间。
题解
对于
a
≠
0
,
b
≠
0
,
c
=
0
a\neq 0,b \neq 0,c = 0
a=0,b=0,c=0的情况,我们考虑
f
[
i
]
[
j
]
f[i][j]
f[i][j]对
f
[
n
]
[
n
]
f[n][n]
f[n][n]的贡献,则原式可以理解为从
(
i
,
j
)
(i,j)
(i,j)出发,每一步可以选择向下走或向右走,向下走代价为
×
b
\times b
×b,向右走代价为
×
a
\times a
×a,到
(
n
,
n
)
(n,n)
(n,n)的所有路径的代价之和。
对于一条路径,一共要向下走
n
−
i
n-i
n−i步,向右走
n
−
j
n-j
n−j步。所以贡献为
a
n
−
i
∗
b
n
−
j
a^{n-i}*b^{n-j}
an−i∗bn−j,路径条数为
C
2
n
−
i
−
j
n
−
i
C_{2n-i-j}^{n-i}
C2n−i−jn−i,乘起来即可。
我们只需要求
∑
i
=
2
n
f
[
1
]
[
i
]
+
f
[
i
]
[
1
]
\sum_{i=2}^{n}f[1][i]+f[i][1]
∑i=2nf[1][i]+f[i][1]即可
由于路径会重复(
f
[
1
]
[
i
]
f[1][i]
f[1][i]和
f
[
i
]
[
1
]
f[i][1]
f[i][1]是题目给的,不是自己求的),所以我们对于第一行第一步要将其向下,第一列第一步要将其向右走。
于是我们的答案就是
∑
i
=
2
n
C
2
n
−
i
−
2
n
−
2
×
(
f
[
1
]
[
i
]
×
a
n
−
i
×
b
n
−
1
+
f
[
i
]
[
1
]
×
a
n
−
1
×
b
n
−
i
)
\sum_{i=2}^{n}C_{2n-i-2}^{n-2} \times (f[1][i] \times a^{n-i} \times b^{n-1} +f[i][1] \times a^{n-1}\times b^{n-i} )
∑i=2nC2n−i−2n−2×(f[1][i]×an−i×bn−1+f[i][1]×an−1×bn−i)。
然后我们来考虑
c
≠
0
c \neq 0
c=0的情况:
显然,我们可以发现,若我们令
g
[
i
]
[
j
]
=
f
[
i
]
[
j
]
+
k
g[i][j]=f[i][j]+k
g[i][j]=f[i][j]+k,且
g
[
i
]
[
j
]
=
a
×
g
[
i
]
[
j
−
1
]
+
b
×
g
[
i
−
1
]
[
j
]
g[i][j]=a \times g[i][j-1]+b \times g[i-1][j]
g[i][j]=a×g[i][j−1]+b×g[i−1][j],那么问题就转化为了上面的情况。
所以我们将
g
[
i
]
[
j
]
=
f
[
i
]
[
j
]
+
k
g[i][j]=f[i][j]+k
g[i][j]=f[i][j]+k代入,解得
k
=
c
a
+
b
−
1
k=\frac{c}{a+b-1}
k=a+b−1c。于是我们就能通过上述情况求出
g
[
n
]
[
n
]
g[n][n]
g[n][n],然后减去
k
k
k就是答案
f
[
n
]
[
n
]
f[n][n]
f[n][n]了。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
ll k=0,f=1;char ch;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')k=k*10+ch-'0',ch=getchar();
return k*f;
}
const int N=4e5+10;
const int P=1e6+3;
ll ksm(ll a,ll b){
ll s=1;while(b){
if(b&1)s=s*a%P;
a=a*a%P;b>>=1;
}
return s;
}
ll n,f,l[N],jc[N],r[N],ans,a,b,c,k;
ll C(ll a,ll b){
if(b>a)return 0;
return jc[a]*ksm(jc[b],P-2)%P*ksm(jc[a-b],P-2)%P;
}
int main(){
n=read();a=read();b=read();c=read();k=c*ksm((a+b-1)%P,P-2)%P;
for(int i=1;i<=n;++i)l[i]=read(),l[i]=(l[i]+k)%P;
for(int i=1;i<=n;++i)r[i]=read(),r[i]=(r[i]+k)%P;
jc[0]=1;
for(int i=1;i<=2*n;++i)jc[i]=jc[i-1]*i%P;
for(int i=2;i<=n;++i){
ll ck=C(n*2-2-i,n-2)*(ksm(a,n-i)*ksm(b,n-1)%P*r[i]%P+ksm(a,n-1)*ksm(b,n-i)%P*l[i]%P)%P;
ans=(ans+ck)%P;
}
printf("%lld\n",(ans-k+P)%P);
return 0;
}