SPOJ GSS系列

来源:互联网 发布:java selenim设置超时 编辑:程序博客网 时间:2024/05/29 04:35

这个系列基本包括了线段树的所有经典案例,把这个做完线段树的基本操作就可以了,,,,当年怎么没人告诉我QAQAQAQ

GSS1 - Can you answer these queries I

传送门

http://www.spoj.com/problems/GSS1/

题目大意

给定序列,询问区间[L,R]内的最大子段和

题解

线段合并基本操作,每个区间记录
w[a,3]:该区间最大子段和
w[a,4]:该区间含左端点的最大子段和
w[a,5]:该区间含右端点的最大子段和
pushup的话自己yy一下就好了

const maxn=50005;type mm=record mx,mxl,mxr:longint; end;var w:array[0..4*maxn,1..5]of longint; sum:array[0..maxn]of longint; i,j,k:longint; n,m,a,b,c:longint;function max(a,b:longint):longint;begin if a>b then exit(a) else exit(b); end;procedure pushup(a:longint);begin if w[a,1]=w[a,2] then exit; w[a,3]:=max(max(w[a<<1,3],w[a<<1+1,3]),w[a<<1,5]+w[a<<1+1,4]); w[a,4]:=max(w[a<<1,4],sum[w[a<<1,2]]-sum[w[a<<1,1]-1]+w[a<<1+1,4]); w[a,5]:=max(w[a<<1+1,5],sum[w[a<<1+1,2]]-sum[w[a<<1+1,1]-1]+w[a<<1,5]);end;procedure build(a,l,r:longint);var mid:longint;begin w[a,1]:=l; w[a,2]:=r; if l=r then begin read(w[a,3]); w[a,4]:=w[a,3]; w[a,5]:=w[a,3]; sum[l]:=sum[l-1]+w[a,3]; exit; end; mid:=(l+r)>>1; build(a<<1,l,mid); build(a<<1+1,mid+1,r); pushup(a);end;function query(a,l,r:longint):mm;var mid:longint; tt,tt1,tt2:mm;begin if (w[a,1]=l)and(w[a,2]=r) then begin tt.mx:=w[a,3]; tt.mxl:=w[a,4]; tt.mxr:=w[a,5]; exit(tt); end; mid:=(w[a,1]+w[a,2])>>1; if r<=mid then exit(query(a<<1,l,r)) else if l>mid then exit(query(a<<1+1,l,r)) else begin  tt1:=query(a<<1,l,mid); tt2:=query(a<<1+1,mid+1,r);  tt.mx:=max(max(tt1.mx,tt2.mx),tt1.mxr+tt2.mxl);  tt.mxl:=max(tt1.mxl,sum[mid]-sum[l-1]+tt2.mxl);  tt.mxr:=max(tt2.mxr,sum[r]-sum[mid]+tt1.mxr);  exit(tt); end;end;begin readln(n); sum[0]:=0; build(1,1,n); readln(m); for i:=1 to m do  begin   readln(a,b);   writeln(query(1,a,b).mx);  end;end.

GSS2 - Can you answer these queries II

传送门

http://www.spoj.com/problems/GSS2/

题目大意

给定序列,查询[L,R]内最大子段和,相同的数只贡献一次

题解

经典的离线操作,HH的项链

const maxn=100005;type mm=record mx,mxl,mxr,sum:longint; end;var w:array[0..4*maxn,1..6]of longint; x:array[0..maxn,1..3]of longint; y:array[-maxn..maxn]of longint; ans,t,z:array[0..maxn]of longint; i,j,k:longint; n,m,a,b:longint;procedure sort(l,r:longint);var i,j,a,b,c:longint;begin i:=l; j:=r; a:=x[(l+r)>>1,1]; c:=x[(l+r)>>1,2]; repeat  while (x[i,1]<a)or((x[i,1]=a)and(x[i,2]<c)) do inc(i);  while (a<x[j,1])or((x[j,1]=a)and(x[j,2]>c)) do dec(j);  if not(i>j) then   begin    b:=x[i,1]; x[i,1]:=x[j,1]; x[j,1]:=b;    b:=x[i,2]; x[i,2]:=x[j,2]; x[j,2]:=b;    b:=x[i,3]; x[i,3]:=x[j,3]; x[j,3]:=b;    inc(i); dec(j);   end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r);end;function max(a,b:longint):longint;begin if a>b then exit(a) else exit(b);end;procedure pushup(a:longint);begin if w[a,1]=w[a,2] then exit; w[a,3]:=max(max(w[a<<1,3],w[a<<1+1,3]),w[a<<1,5]+w[a<<1+1,4]); w[a,4]:=max(w[a<<1,4],w[a<<1,6]+w[a<<1+1,4]); w[a,5]:=max(w[a<<1+1,5],w[a<<1+1,6]+w[a<<1,5]); w[a,6]:=w[a<<1,6]+w[a<<1+1,6];end;procedure build(a,l,r:longint);var mid:longint;begin w[a,1]:=l; w[a,2]:=r; w[a,3]:=-maxn; w[a,4]:=-maxn; w[a,5]:=-maxn; w[a,6]:=-maxn; if l=r then exit; mid:=(l+r)>>1; build(a<<1,l,mid); build(a<<1+1,mid+1,r);end;procedure update(a,b,c:longint);var mid:longint;begin if w[a,1]=w[a,2] then begin w[a,3]:=c; w[a,4]:=c; w[a,5]:=c; w[a,6]:=c; exit; end; mid:=(w[a,1]+w[a,2])>>1; if b<=mid then update(a<<1,b,c) else update(a<<1+1,b,c); pushup(a);end;function query(a,l,r:longint):mm;var mid:longint; tt,tt1,tt2:mm;begin if (w[a,1]=l)and(w[a,2]=r) then begin tt.mx:=w[a,3]; tt.mxl:=w[a,4]; tt.mxr:=w[a,5]; tt.sum:=w[a,6]; exit(tt); end; mid:=(w[a,1]+w[a,2])>>1; if r<=mid then exit(query(a<<1,l,r)) else if l>mid then exit(query(a<<1+1,l,r)) else begin  tt1:=query(a<<1,l,mid); tt2:=query(a<<1+1,mid+1,r);  tt.mx:=max(max(tt1.mx,tt2.mx),tt1.mxr+tt2.mxl);  tt.mxl:=max(tt1.mxl,tt1.sum+tt2.mxl);  tt.mxr:=max(tt2.mxr,tt2.sum+tt1.mxr);  tt.sum:=tt1.sum+tt2.sum;  exit(tt); end;end;begin readln(n); build(1,1,n); for i:=1 to n do  read(t[i]); for i:=1 to n do  begin   a:=t[i];   if y[a]=0 then update(1,i,a) else z[y[a]]:=i;   y[a]:=i;  end; readln(m); for i:=1 to m do  begin   readln(x[i,1],x[i,2]);   x[i,3]:=i;  end; sort(1,m); x[0,1]:=1; for i:=1 to m do  begin   for j:=x[i-1,1] to x[i,1]-1 do    begin     update(1,j,0);     if z[j]<>0 then update(1,z[j],t[j]);    end;   ans[x[i,3]]:=query(1,x[i,1],x[i,2]).mx;  end; for i:=1 to m do  if ans[i]<0  then writeln(0)  else writeln(ans[i]);end.

GSS3 - Can you answer these queries III

传送门

http://www.spoj.com/problems/GSS3/

题目大意

单点修改+查询区间最大子段和

题解

同GSS1,单点修改,,,

const maxn=100005;type mm=record mx,mxl,mxr,sum:longint; end;var w:array[0..4*maxn,1..6]of longint; i,j,k:longint; n,m,a,b,c:longint;function max(a,b:longint):longint;begin if a>b then exit(a) else exit(b);end;procedure pushup(a:longint);begin if w[a,1]=w[a,2] then exit; w[a,3]:=max(max(w[a<<1,3],w[a<<1+1,3]),w[a<<1,5]+w[a<<1+1,4]); w[a,4]:=max(w[a<<1,4],w[a<<1,6]+w[a<<1+1,4]); w[a,5]:=max(w[a<<1+1,5],w[a<<1+1,6]+w[a<<1,5]); w[a,6]:=w[a<<1,6]+w[a<<1+1,6];end;procedure build(a,l,r:longint);var mid:longint;begin w[a,1]:=l; w[a,2]:=r; if l=r then begin read(w[a,3]); w[a,4]:=w[a,3]; w[a,5]:=w[a,3]; w[a,6]:=w[a,3]; exit; end; mid:=(l+r)>>1; build(a<<1,l,mid); build(a<<1+1,mid+1,r); pushup(a);end;procedure update(a,b,c:longint);var mid:longint;begin if w[a,1]=w[a,2] then begin w[a,3]:=c; w[a,4]:=c; w[a,5]:=c; w[a,6]:=c; exit; end; mid:=(w[a,1]+w[a,2])>>1; if b<=mid then update(a<<1,b,c) else update(a<<1+1,b,c); pushup(a);end;function query(a,l,r:longint):mm;var mid:longint; tt,tt1,tt2:mm;begin if (w[a,1]=l)and(w[a,2]=r) then begin tt.mx:=w[a,3]; tt.mxl:=w[a,4]; tt.mxr:=w[a,5]; tt.sum:=w[a,6]; exit(tt); end; mid:=(w[a,1]+w[a,2])>>1; if r<=mid then exit(query(a<<1,l,r)) else if l>mid then exit(query(a<<1+1,l,r)) else begin  tt1:=query(a<<1,l,mid); tt2:=query(a<<1+1,mid+1,r);  tt.mx:=max(max(tt1.mx,tt2.mx),tt1.mxr+tt2.mxl);  tt.mxl:=max(tt1.mxl,tt1.sum+tt2.mxl);  tt.mxr:=max(tt2.mxr,tt2.sum+tt1.mxr);  tt.sum:=tt1.sum+tt2.sum;  exit(tt); end;end;begin readln(n); build(1,1,n); readln(m); for i:=1 to m do  begin   readln(a,b,c);   if a=0   then update(1,b,c)   else writeln(query(1,b,c).mx);  end;end.

GSS4 - Can you answer these queries IV

传送门

http://www.spoj.com/problems/GSS4/

题目大意

区间开根号+区间和查询

题解

没啥说的….

const maxn=100005;var w:array[0..4*maxn,1..3]of int64; i,j,k:longint; n,m,a,b,c,d,t:longint;procedure build(a,l,r:longint);var mid:longint;begin w[a,1]:=l; w[a,2]:=r; if l=r then begin read(w[a,3]); exit; end; mid:=(l+r)>>1; build(a<<1,l,mid); build(a<<1+1,mid+1,r); w[a,3]:=w[a<<1,3]+w[a<<1+1,3];end;procedure update(a,l,r:longint);var mid:longint;begin if w[a,3]<=w[a,2]-w[a,1]+1 then exit; if w[a,1]=w[a,2] then begin w[a,3]:=trunc(sqrt(w[a,3])); exit; end; mid:=(w[a,1]+w[a,2])>>1; if r<=mid then update(a<<1,l,r) else if l>mid then update(a<<1+1,l,r) else begin update(a<<1,l,mid); update(a<<1+1,mid+1,r); end; w[a,3]:=w[a<<1,3]+w[a<<1+1,3];end;function query(a,l,r:longint):int64;var mid:longint;begin if (w[a,1]=l)and(w[a,2]=r) then exit(w[a,3]); mid:=(w[a,1]+w[a,2])>>1; if r<=mid then exit(query(a<<1,l,r)) else if l>mid then exit(query(a<<1+1,l,r)) else exit(query(a<<1,l,mid)+query(a<<1+1,mid+1,r));end;begin t:=0; while not eof do  begin   inc(t); writeln('Case #',t,':');   fillchar(w,sizeof(w),0);   readln(n);   build(1,1,n);   readln(m);   for i:=1 to m do    begin     readln(a,b,c); if b>c then begin d:=b; b:=c; c:=d; end;     if a=0     then update(1,b,c)     else writeln(query(1,b,c));    end;  end;end.

GSS5 - Can you answer these queries V

传送门

http://www.spoj.com/problems/GSS5/

题目大意

[L1R1][L2R2]

题解

分类讨论
L1<=R1<=L2<=R2sum[R1+1..L21][L1R1][L2R2]
L1<=L2<=R1<=R2

  • L[L1,L2]

    • R[L2,R1]:[L1,L2]+[L2,R1]
    • R[R1,R2]:[L1,L2]+sum[L2,R1]+[R1,R2]
  • L[L2,R1]

    • R[L2,R1]:[L2,R1]
    • R[R1,R2]:[L2,R1]+[R1,R2]
const maxn=10005;type mm=record mx,mxl,mxr,sum:longint; end;var w:array[0..4*maxn,1..6]of longint; i,j,k,l:longint; n,m,t,a,b,c,d,ans,ans1,ans2,ans3:longint;function max(a,b:longint):longint;begin if a>b then exit(a) else exit(b);end;procedure pushup(a:longint);begin if w[a,1]=w[a,2] then exit; w[a,3]:=max(max(w[a<<1,3],w[a<<1+1,3]),w[a<<1,5]+w[a<<1+1,4]); w[a,4]:=max(w[a<<1,4],w[a<<1,6]+w[a<<1+1,4]); w[a,5]:=max(w[a<<1+1,5],w[a<<1+1,6]+w[a<<1,5]); w[a,6]:=w[a<<1,6]+w[a<<1+1,6];end;procedure build(a,l,r:longint);var mid:longint;begin w[a,1]:=l; w[a,2]:=r; if l=r then begin read(w[a,3]); w[a,4]:=w[a,3]; w[a,5]:=w[a,3]; w[a,6]:=w[a,3]; exit; end; mid:=(l+r)>>1; build(a<<1,l,mid); build(a<<1+1,mid+1,r); pushup(a);end;function query(a,l,r:longint):mm;var mid:longint; tt,tt1,tt2:mm;begin tt.mx:=0; tt.mxr:=0; tt.mxl:=0; tt.sum:=0; if l>r then exit(tt); if (w[a,1]=l)and(w[a,2]=r) then begin tt.mx:=w[a,3]; tt.mxl:=w[a,4]; tt.mxr:=w[a,5]; tt.sum:=w[a,6]; exit(tt); end; mid:=(w[a,1]+w[a,2])>>1; if r<=mid then exit(query(a<<1,l,r)) else if l>mid then exit(query(a<<1+1,l,r)) else begin  tt1:=query(a<<1,l,mid); tt2:=query(a<<1+1,mid+1,r);  tt.mx:=max(max(tt1.mx,tt2.mx),tt1.mxr+tt2.mxl);  tt.mxl:=max(tt1.mxl,tt1.sum+tt2.mxl);  tt.mxr:=max(tt2.mxr,tt2.sum+tt1.mxr);  tt.sum:=tt1.sum+tt2.sum;  exit(tt); end;end;begin readln(t); for l:=1 to t do  begin   fillchar(w,sizeof(w),0);   read(n); build(1,1,n);   readln(m);   for i:=1 to m do    begin     readln(a,b,c,d);     if b<c     then begin      ans:=query(1,b,c).sum;      if b-1>=a then inc(ans,max(0,query(1,a,b-1).mxr));      if c+1<=d then inc(ans,max(0,query(1,c+1,d).mxl));     end     else begin      ans1:=query(1,c,c).sum;      if a+1<=c then inc(ans1,max(0,query(1,a,c-1).mxr));      if c+1<=d then inc(ans1,max(0,query(1,c+1,d).mxl));      ans2:=query(1,b,b).sum;      if a+1<=b then inc(ans2,max(0,query(1,a,b-1).mxr));      if b+1<=d then inc(ans2,max(0,query(1,b+1,d).mxl));      ans3:=query(1,c,b).mx;      ans:=max(max(ans1,ans2),ans3);     end;     writeln(ans);    end;  end;end.
0 0