题意:求两段不相交的连续子序列的和的最大值.如下:
水题,以前刚学线段树的时候写的,想到可以用线段树,一激动写了NlogN的.其实可以O(N)的.
code(600多MS,勿看):
type node=record
l,r,num:longint;
end;
const oo=600000000;
maxn=51000;
var f1,f2,a:array[0..51000] of longint;
t:array[0..maxn*5] of node;
datanum,d,n,s,ans,i,max1,max2:longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a); exit(b);
end;
procedure build(l,r,i:longint);
var mid:longint;
begin
t[i].l:=l;
t[i].r:=r;
if l=r then
begin t[i].num:=f2[l]; exit; end;
mid:=(l+r) shr 1;
build(l,mid,i<<1);
build(mid+1,r,i<<1+1);
t[i].num:=max(t[i<<1].num,t[i<<1+1].num);
end;
procedure change(k,num,i:longint);
begin
if (t[i].r=t[i].l) then
begin t[i].num:=num; exit; end
else begin
if (k<=t[i<<1].r) then change(k,num,i<<1)
else change(k,num,i<<1+1);
t[i].num:=max(t[i<<1].num,t[i<<1+1].num);
end;
end;
function getans(l,r,i:longint):longint;
var ans1,ans2,mid:longint;
begin
if (t[i].l=l)and(t[i].r=r) then exit(t[i].num);
ans1:=-oo;
ans2:=-oo;
mid:=(t[i].l+t[i].r)>>1;
if r<=mid then ans1:=getans(l,r,i<<1)
else if l>mid then ans2:=getans(l,r,i<<1+1)
else begin
ans1:=getans(l,mid,i<<1);
ans2:=getans(mid+1,r,i<<1+1);
end;
exit(max(ans1,ans2));
end;
begin
readln(datanum);
readln;
for d:=1 to datanum do
begin
readln(n);
fillchar(f1,sizeof(f1),0);
fillchar(f2,sizeof(f2),0);
for i:=1 to n do read(a[i]);
for i:=1 to n do
f1[i]:=max(f1[i-1]+a[i],a[i]);
for i:=n downto 1 do
f2[i]:=max(f2[i+1]+a[i],a[i]);
build(1,n,1);
ans:=-oo;
for i:=1 to n-1 do
begin
max1:=f1[i];
max2:=getans(i+1,n,1);
if max1+max2>ans then
ans:=max1+max2;
end;
writeln(ans);
readln;
end;
end.