题意:求两段不相交的连续子序列的和的最大值.如下:
水题,以前刚学线段树的时候写的,想到可以用线段树,一激动写了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.