自从上一次线段树写挂了以后,心里一直不爽!!!
线段树都能写挂。。。。
于是我又找了一些题。
因为临近noip了,就找了点简单题,难的没写出来,调试要花好久。。
我一旦做的题目错了,就会一直找错,直到3~4天都没发现才会放弃,浪费好多时间,于是不敢找难的
这个题目是动态求区间最大连续和,算是一道基本线段树吧= - =
只要记录从左边开始的最大值maxl,右边开始的最大值maxr,区间中的最大值max以及区间和sum
建树时,MAXL[k]:=max{maxl[k*2],sum[k*2]+maxl[k*2+1]} maxr[k]:=max{maxr[k*2+1],sum[k*2]+maxr[k*2]};
max[k]:=max{max[k*2],max[k*2+1],maxr[k*2]+maxl[k*2+1]};
然后修改时,思路一样,找到改的点,然后对从根到该节点所有路径做一遍建树的操作即可。
求答案时,我用了几个变参记录孩子在所给区间的maxl maxr max 以及sum (和数组不一样)用来更改本身节点的相应值,和建树时差不多。
= - =还有一个注意点,就是 会有读入x y y<x的情况= - =
code:(写的有点丑和长了= - =。。我觉得work和change能合在一起,然后边读入边change,但是这样时间会多一点。。)
var
maxl,maxr,sum,max,zuo,you,a:array[0..1100000] of longint;
z,ss,n,m,i,k,x,y,ll,rr,mm:longint;
function mx(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
procedure work(k,l,r:longint);
var
m:longint;
begin
zuo[k]:=l;
you[k]:=r;
if (l=r) then
begin
max[k]:=a[l];
maxl[k]:=a[l];
maxr[k]:=a[l];
sum[k]:=a[l];
exit;
end;
m:=(l+r) div 2;
work(k*2,l,m);
work(k*2+1,m+1,r);
max[k]:=mx(max[k*2],max[k*2+1]);
max[k]:=mx(max[k],maxr[k*2]+maxl[k*2+1]);
maxl[k]:=mx(maxl[k*2],sum[k*2]+maxl[k*2+1]);
maxr[k]:=mx(maxr[k*2+1],sum[k*2+1]+maxr[k*2]);
sum[k]:=sum[k*2]+sum[k*2+1];
end;
procedure find(k,u,v:longint;var ll,rr,mm,ss:longint);
var
m,l,r,ll1,ll2,rr1,rr2,ss1,ss2,mm1,mm2:longint;
begin
l:=zuo[k];r:=you[k];
if (l>=U) and (r<=v) then
begin
ll:=maxl[k];
rr:=maxr[k];
mm:=max[k];
ss:=sum[k];
exit;
end;
m:=(l+r) div 2;
ll:=-maxlongint;rr:=-maxlongint;mm:=-maxlongint;ss:=-maxlongint;
ll1:=-maxlongint;rr1:=-maxlongint;mm1:=-maxlongint;ss1:=-maxlongint;
ll2:=-maxlongint;rr2:=-maxlongint;mm2:=-maxlongint;ss2:=-maxlongint;
if (u<=m) then find(k*2,u,v,ll1,rr1,mm1,ss1);
if (v>m) then find(k*2+1,u,v,ll2,rr2,mm2,ss2);
if (ll1>-maxlongint) and (ll2=-maxlongint) then
begin
ll:=ll1;
rr:=rr1;
mm:=mm1;
ss:=ss1;
end;
if (ll1=-maxlongint) and (ll2>-maxlongint) then
begin
ll:=ll2;
rr:=rr2;
mm:=mm2;
ss:=ss2;
end;
if (ll1>-maxlongint) and (ll2>-maxlongint) then
begin
ll:=mx(ll1,ss1+ll2);
rr:=mx(rr2,ss2+rr1);
mm:=mx(mm1,mm2);
mm:=mx(mm,rr1+ll2);
ss:=ss1+ss2;
end;
end;
procedure change(k,x,y:longint);
var
l,r,m:longint;
begin
l:=zuo[k];
r:=you[k];
if (l=x) and (l=r) then
begin
max[k]:=y;
maxl[k]:=y;
maxr[k]:=y;
sum[k]:=y;
exit;
end;
m:=(l+r) div 2;
if x<=m then change(k*2,x,y);
if x>m then change(k*2+1,x,y);
max[k]:=mx(max[k*2],max[k*2+1]);
max[k]:=mx(max[k],maxr[k*2]+maxl[k*2+1]);
maxl[k]:=mx(maxl[k*2],sum[k*2]+maxl[k*2+1]);
maxr[k]:=mx(maxr[k*2+1],sum[k*2+1]+maxr[k*2]);
sum[k]:=sum[k*2]+sum[k*2+1];
end;
begin
read(n,m);
for i:=1 to n do
read(a[i]);
work(1,1,n);
for i:=1 to m do
begin
read(k);
if k=1 then
begin
read(x,y);
if y<x then
begin
z:=x;
x:=y;
y:=z;
end;
find(1,x,y,ll,rr,mm,ss);
writeln(mm);
end;
if k=2 then
begin
read(x,y);
change(1,x,y);
end;
end;
end.
最后所有数据一共花了3.7s 好像一点慢了些。。。