您的位置:首页 > 其它

【NOI2017模拟4.5】数字格

2017-04-10 10:58 337 查看

题目

Description

菁菁堂有一块数字格,那是王解体最喜欢去的地方。

传说中,这条气势磅礴的数字格,有N行N列,每一个格子里均有一个数。

敢于挑战自己的王解体决定来挑战这道通过率为百分之九十九的题目。

格子的第一行及第一列均是给定的:

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)时,通过率将达到百分之百。

Input

题目包含多组测试数据,每组测试数据占3行。

对于每组测试数据:

第一行包含4个整数N,a,b,c。

第二行包含N个整数,表示l[1],…,l

第三行包含N个整数,表示t[1],…,t

Output

对于每组数据,输出一行,包含一个整数,表示王解体得到的答案。

Sample Input

3 0 0 0

0 0 2

0 3 0

4 3 5 2

7 1 4 3

7 4 4 8

Sample Output

0

41817

Data Constraint

10%的数据:N<=1000

30%的数据:N<=10000

100%的数据:N<=200000,a,b,c<=1000000,l[1]=t[1],1<=l[k],t[k]<=1000000

题解

我们首先考虑第一行和第一列中的数的a,b对于答案的贡献

设p(i,j)

可以发现就是Cn−in−i+n−j,那么a,b对于答案的贡献十分好求

然后我们考虑c对于答案的贡献,朴素的计算方法应该是∑ni=2∑ni=2Cn−in−i+n−j∗an−ibn−j∗c

然后我们发现可以从终点开始快速的求出每一个斜率为4/π的线覆盖的点的贡献和

就是f[i]=(a+b)*f[i-1],这个手玩一下还是十分显然的

但是我们发现过了对角线之后这个东西开始超过了我们的区间,所以我们每次要减去最上面和最左边的那一个,可以发现这两个位置的第一步是固定的,所以不要被套路了

然后我们就可以在线性的时间内解决这一问题了(不包括快速幂的话)

贴代码

const md=1000003;
var
l,t:array[0..200005]of int64;
s,b1,a1:array[0..400005]of int64;
i,j:longint;
n,a,b,c,x,y,z,ans,tc:int64;
function quickmi(x,y:int64):int64;
var
p,t:int64;
begin
x:=x mod md;
p:=1;
while y>0 do
begin
if y mod 2=1 then p:=(p*x) mod md;
x:=(x*x) mod md;
y:=y div 2;
end;
exit(p);
end;
procedure work;
var
pp:longint;
begin
readln(n,a,b,c);
s[0]:=1;
for i:=1 to 2*n do s[i]:=(s[i-1]*i) mod md;
a1[0]:=1;
for i:=1 to n do a1[i]:=(a1[i-1]*a) mod md;
b1[0]:=1;
for i:=1 to n do b1[i]:=(b1[i-1]*b) mod md;
a1[n+1]:=quickmi(b,n);
for i:=1 to n do
begin
read(pp);
if i=1 then continue;
x:=(quickmi(s[n-2]*s[n-i],md-2)*s[2*n-i-2]) mod md;
l[i]:=x;
y:=(b1[n-i]*a1[n-1]) mod md;
//y:=(quickmi(b,n-i)*quickmi(a,n-1)) mod md;
x:=(x*y) mod md;
x:=(x*pp) mod md;
ans:=(ans+x) mod md;
end;
readln;
for i:=1 to n do
begin
read(pp);
if i=1 then continue;
x:=l[i];
y:=(b1[n-1]*a1[n-i]) mod md;
//y:=(quickmi(b,n-1)*quickmi(a,n-i)) mod md;
x:=(x*y) mod md;
x:=(x*pp) mod md;
ans:=(ans+x) mod md;
end;
readln;
z:=1;
for i:=1 to n-2 do
begin
z:=(z*(a+b)) mod md;
ans:=(ans+z*c) mod md;
end;
for i:=0 to n-3 do
begin
z:=(z*(a+b)) mod md;
x:=(quickmi(s[n-2]*s[i],md-2)*s[n-2+i]) mod md;
y:=(a1[i]*b1[n-1]);
y:=y+(a1[n-1]*b1[i]) mod md;
y:=(y*x) mod md;
z:=(z+md-y) mod md;
ans:=(ans+c*z) mod md;
end;
ans:=(ans+c) mod md;
writeln(ans);
end;
begin
assign(input,'matrix.in'); reset(input);
assign(output,'matrix.out'); rewrite(output);
while not eof do
begin
ans:=0;
work;
end;
close(input); close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: