表示在线段树上被秋哥虐了~~~
题目1:在a[1...n]中,给出m个询问(l,r),每次回答(l,r)中最大子段和。
初始化:
ls——当前区间由左端点向右最大子区间
rs——当前区间由右端点向左最大子区间
ms——当前区间最大子区间
sum——当前子段和
修改:lt左子树,rt右子树,it当前子树
ls[it]:=max(ls[lt],sum[lt]+ls[rt])
rs[it]:=max(rs[rt],sum[rt]+rs[lt])
ms[it]:=max(max(ms[lt],ms[rt]),rs[lt]+ls[rt])
sum[it]:=sum[lt]+sum[rt]
查询:ask1,askl,askr
1、对于查询到的左区间:
ask1:=max(ask1,max(ms[l],askl+ls[l]))
askl:=max(askl+sum[l],rs[l])
2、对于查询到的右区间:
ask1:=max(ask1,max(ms[r],askr+rs[r]))
askr:=max(askr+sum[r],ls[r])
线段树直接过,spoj上有这系列练习题
uses math;
var ans,n,m,m1:longint;
sum,ms,ls,rs:array[1..131072]of longint;
procedure origin;
begin
m1:=1;
while m1<n+2 do m1:=m1<<1;m1:=m1-1;
fillchar(ms,sizeof(ms),129);
end;
procedure change(x,y:longint);
var lt,rt:longint;
begin
x:=x+m1;
sum[x]:=y;ls[x]:=y;rs[x]:=y;ms[x]:=y;
x:=x>>1;
while x<>0 do begin
lt:=x<<1;rt:=x<<1+1;
sum[x]:=sum[lt]+sum[rt];
ls[x]:=max(ls[lt],sum[lt]+ls[rt]);
rs[x]:=max(rs[rt],sum[rt]+rs[lt]);
ms[x]:=max(max(ms[lt],ms[rt]),rs[lt]+ls[rt]);
x:=x>>1
end
end;
function ask(l,r:longint):longint;
var ask1,askl,askr:longint;
begin
l:=l+m1-1;r:=r+m1+1;ask:=-maxlongint;
ask1:=-100000000;askl:=ask1;askr:=ask1;
while not(l xor r=1) do begin
if l and 1=0 then begin
ask1:=max(ask1,max(ms[l+1],askl+ls[l+1]));
askl:=max(rs[l+1],askl+sum[l+1])
end;
if r and 1=1 then begin
ask1:=max(ask1,max(ms[r-1],askr+rs[r-1]));
askr:=max(ls[r-1],askr+sum[r-1])
end;
l:=l>>1;r:=r>>1
end;
exit(max(ask1,askl+askr))
end;
procedure init;
var i,x,y:longint;
begin
readln(n);
origin;
for i:=1 to n do begin
read(x);change(i,x)
end;
readln(m);
for i:=1 to m do begin
readln(x,y);ans:=ask(x,y);
writeln(ans)
end
end;
begin
assign(input,'lostmat.in');reset(input);
assign(output,'lostmat.out');rewrite(output);
init;
close(input);close(output)
end.