BZOJ1500:[NOI2005]维修数列

Description

Input

输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

Output

对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

Sample Input

9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM

Sample Output

-1
10
1
10

题解:

平衡树的模板题,要用上翻转标记、统一赋值标记,维护区间和、区间最大左子串、区间最大右子串、区间最大子串。

代码:

  1 var
  2   n,m,rt,cnt,i,j,k,tot,vall,ql,qr:longint;
  3   a,id,fa,sum,size,v,mx,lx,rx,tag,rev:array[0..1000005]of longint;
  4   c:array[0..1000005,0..2]of longint;
  5   q:array[0..1000005]of longint;
  6   ch:array[0..3]of char;
  7 function max(a,b:longint):longint;
  8 begin
  9   if a>b then exit(a);
 10   exit(b);
 11 end;
 12 procedure update(x:longint);
 13 var l,r:longint;
 14 begin
 15   l:=c[x,0]; r:=c[x,1];
 16   sum[x]:=sum[l]+sum[r]+v[x]; 
 17   size[x]:=size[l]+size[r]+1;
 18   mx[x]:=max(mx[l],mx[r]);
 19   mx[x]:=max(mx[x],rx[l]+v[x]+lx[r]); 
 20   lx[x]:=max(lx[l],sum[l]+v[x]+lx[r]);
 21   rx[x]:=max(rx[r],sum[r]+v[x]+rx[l]);
 22 end;
 23 procedure pushdown(x:longint);
 24 var l,r,ttt:longint;
 25 begin
 26   l:=c[x,0]; r:=c[x,1];
 27   if tag[x]>0 then
 28   begin
 29     tag[x]:=0; rev[x]:=0;
 30     if l>0 then begin tag[l]:=1; v[l]:=v[x]; sum[l]:=v[x]*size[l]; end;
 31     if r>0 then begin tag[r]:=1; v[r]:=v[x]; sum[r]:=v[x]*size[r]; end;
 32     if v[x]>=0 then
 33     begin
 34       if l>0 then begin mx[l]:=sum[l]; rx[l]:=sum[l]; lx[l]:=sum[l]; end;
 35       if r>0 then begin mx[r]:=sum[r]; rx[r]:=sum[r]; lx[r]:=sum[r]; end;
 36     end else
 37     begin
 38       if l>0 then begin lx[l]:=0; rx[l]:=0; mx[l]:=v[x]; end;
 39       if r>0 then begin lx[r]:=0; rx[r]:=0; mx[r]:=v[x]; end;
 40     end;
 41   end;
 42   if rev[x]>0 then
 43   begin
 44     rev[x]:=rev[x] xor 1; rev[l]:=rev[l] xor 1; rev[r]:=rev[r] xor 1;
 45     ttt:=lx[l]; lx[l]:=rx[l]; rx[l]:=ttt; ttt:=lx[r]; lx[r]:=rx[r]; rx[r]:=ttt;
 46     ttt:=c[l,0]; c[l,0]:=c[l,1]; c[l,1]:=ttt; ttt:=c[r,0]; c[r,0]:=c[r,1]; c[r,1]:=ttt;
 47   end;
 48 end;  
 49 procedure rotate(x:longint;var k:longint);
 50 var y,z,l,r:longint;
 51 begin
 52   y:=fa[x]; z:=fa[y];
 53   if c[y,1]=x then l:=1 else l:=0; r:=l xor 1;
 54   if y=k then k:=x
 55   ELSE BEGIN if c[z,1]=y then c[z,1]:=x else c[z,0]:=x; END;
 56   fa[c[x,r]]:=y; fa[y]:=x; fa[x]:=z;
 57   c[y,l]:=c[x,r]; c[x,r]:=y;
 58   update(y); update(x);
 59 end;
 60 procedure splay(x:longint; var k:longint);
 61 var y,z:longint;
 62 begin
 63   while x<>k do
 64   begin
 65     y:=fa[x]; z:=fa[y];
 66     if y<>k then
 67     begin
 68       if(c[y,0]=x)xor(c[z,0]=y)then rotate(x,k)
 69       else rotate(y,k);
 70     end;
 71     rotate(x,k);
 72   end;
 73 end;
 74 function find(x,rk:longint):longint;
 75 var l,r:longint;
 76 begin
 77   pushdown(x);
 78   l:=c[x,0]; r:=c[x,1];
 79   if size[l]+1=rk then exit(x);
 80   if size[l]>=rk then exit(find(l,rk));
 81   exit(find(r,rk-size[l]-1));
 82 end;
 83 procedure rec(x:longint);
 84 var l,r:longint;
 85 begin
 86   if x=0 then exit;
 87   l:=c[x,0]; r:=c[x,1];
 88   rec(l); rec(r); inc(qr); if qr=1000000 then qr:=1; q[qr]:=x;
 89   fa[x]:=0; c[x,0]:=0; c[x,1]:=0;
 90   tag[x]:=0; rev[x]:=0;
 91 end;
 92 function split(k,tot:longint):longint;
 93 var x,y:longint;
 94 begin
 95   x:=find(rt,k); y:=find(rt,k+tot+1);
 96   splay(x,rt); splay(y,c[x,1]);
 97   exit(c[y,0]);
 98 end;
 99 procedure query(k,tot:longint);
100 var x:longint;
101 begin
102   x:=split(k,tot);
103   writeln(sum[x]);
104 end;
105 procedure modify(k,tot,vall:longint);
106 var x,y,I:longint;
107 begin
108   x:=split(k,tot);  y:=fa[x];
109   v[x]:=vall; tag[x]:=1; sum[x]:=size[x]*vall; 
110   if vall>=0 then begin lx[x]:=sum[x]; rx[x]:=sum[x]; mx[x]:=sum[x]; end
111   else begin lx[x]:=0; rx[x]:=0; mx[x]:=vall; end;
112   update(y); update(fa[y]);
113 end;
114 procedure rever(k,tot:longint);
115 var x,y,ttt:longint;
116 begin
117   x:=split(k,tot); y:=fa[x];
118   if tag[x]=0 then  
119   begin
120     rev[x]:=rev[x]xor 1;
121     ttt:=c[x,0]; c[x,0]:=c[x,1]; c[x,1]:=ttt;
122     ttt:=lx[x]; lx[x]:=rx[x]; rx[x]:=ttt;
123     update(y); update(fa[y]);
124   end;
125 end;
126 procedure erase(k,tot:longint);
127 var x,y:longint;
128 begin
129   x:=split(k,tot); y:=fa[x];
130   rec(x); c[y,0]:=0;
131   update(y); update(fa[y]);
132 end;
133 procedure build(l,r,f:longint);
134 var mid,now,last:longint;
135 begin
136   if l>r then exit;
137   mid:=(l+r)div 2; now:=id[mid]; last:=id[f];
138   if l=r then
139   begin
140     sum[now]:=a[l]; size[now]:=1;
141     tag[now]:=0; rev[now]:=0;
142     if a[l]>=0 then begin lx[now]:=a[l]; rx[now]:=a[l]; mx[now]:=a[l]; end
143     else begin lx[now]:=0; rx[now]:=0; mx[now]:=a[l]; end;
144   end else begin build(l,mid-1,mid); build(mid+1,r,mid); end;
145   v[now]:=a[mid]; fa[now]:=last; update(now);
146   if mid>=f then c[last,1]:=now else c[last,0]:=now;
147 end;
148 procedure insert(k,tot:longint);
149 var i,z,x,y:longint;
150 begin
151   for i:=1 to tot do read(a[i]);
152   for i:=1 to tot do
153   if(ql<>qr)then begin inc(ql); if ql=1000000 then ql:=1; id[i]:=q[ql]; end
154   else begin inc(cnt); id[i]:=cnt; end;
155   build(1,tot,0); z:=id[(1+tot)div 2];
156   x:=find(rt,k+1); y:=find(rt,k+2);
157   splay(x,rt); splay(y,c[x,1]);
158   fa[z]:=y; c[y,0]:=z;
159   update(y); update(x);
160 end;
161 begin
162   readln(n,m); mx[0]:=-100000000; a[1]:=-100000000; a[n+2]:=-100000000;
163   for i:=1 to n do read(a[i+1]); readln;
164   for i:=1 to n+2 do id[i]:=i;
165   build(1,n+2,0);
166   rt:=(n+3)div 2; cnt:=n+2;
167   for i:=1 to m do
168   begin
169     read(ch[0],ch[1],ch[2]);
170     read(ch[3]); while(not eoln)and(ch[3]<>' ')do read(ch[3]);
171     if(ch[0]<>'M')or(ch[2]<>'X')then begin read(k,tot); end;
172     if ch[0]='I' then insert(k,tot);
173     if ch[0]='D' then erase(k,tot);
174     if ch[0]='M' then
175     begin
176       if ch[2]='X' then writeln(mx[rt])
177       else begin read(vall); modify(k,tot,vall); end;
178     end;
179     if ch[0]='R' then rever(k,tot);
180     if ch[0]='G' then query(k,tot);
181     readln;
182   end;
183 end.
PASCAL(Splay)
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 int tr[1000005][10],fa[1000005],a[1000005],root,cnt,n,m,j,k,l,ql,qr,q[1000005];
  4 char s[1000];
  5 int newt(int v)
  6 {
  7     int x; if(ql!=qr){ ql++; if(ql>1000000)ql=1; x=q[ql]; }else x=++cnt;
  8     tr[x][0]=tr[x][1]=tr[x][8]=0; tr[x][7]=-200000;
  9     tr[x][2]=1; tr[x][3]=tr[x][4]=tr[x][9]=v; tr[x][5]=tr[x][6]=max(0,v);
 10     return x;
 11 }
 12 void up(int x)
 13 {
 14     int l=tr[x][0],r=tr[x][1];
 15     tr[x][2]=tr[l][2]+tr[r][2]+1; tr[x][3]=tr[l][3]+tr[r][3]+tr[x][9];
 16     tr[x][4]=max(max(tr[l][4],tr[r][4]),tr[l][6]+tr[x][9]+tr[r][5]);
 17     tr[x][5]=max(tr[l][5],tr[l][3]+tr[x][9]+tr[r][5]); tr[x][6]=max(tr[r][6],tr[l][6]+tr[x][9]+tr[r][3]);
 18 }
 19 void down(int x)
 20 {
 21     if(x==0)return;
 22     int l=tr[x][0],r=tr[x][1]; if(l==0)l=1000001; if(r==0)r=1000001;
 23     int x1=tr[x][7],x2=tr[x][8]; tr[x][7]=-200000; tr[x][8]=0;
 24     if(x1>-200000)
 25     {
 26         tr[l][9]=tr[r][9]=tr[l][7]=tr[r][7]=x1; tr[l][3]=tr[l][2]*x1; tr[r][3]=tr[r][2]*x1;
 27         if(x1>=0)
 28         {
 29             tr[l][4]=tr[l][5]=tr[l][6]=tr[l][3];
 30             tr[r][4]=tr[r][5]=tr[r][6]=tr[r][3];
 31         }else tr[l][4]=tr[r][4]=x1,tr[l][5]=tr[l][6]=tr[r][5]=tr[r][6]=0;
 32     }else
 33     if(x2==1)
 34     {
 35         tr[l][8]^=1; tr[r][8]^=1;
 36         swap(tr[l][0],tr[l][1]); swap(tr[r][0],tr[r][1]);
 37         swap(tr[l][5],tr[l][6]); swap(tr[r][5],tr[r][6]);
 38     }
 39 }
 40 void del(int x)
 41 {
 42     if(x==0)return;
 43     qr++; if(qr>1000000)qr=1; q[qr]=x;
 44     del(tr[x][0]); del(tr[x][1]);
 45 }
 46 int build(int l,int r)
 47 {
 48     int mid=(l+r)/2; int x=newt(a[mid]);
 49     if(l<mid)tr[x][0]=build(l,mid-1); 
 50     fa[tr[x][0]]=x; 
 51     if(mid<r)tr[x][1]=build(mid+1,r); 
 52     fa[tr[x][1]]=x;
 53     up(x); return x;
 54 }
 55 pair<int,int> fl(int x,int y)
 56 {
 57     if(x==0)return make_pair(0,0);
 58     down(x);
 59     if(tr[tr[x][0]][2]>=y)
 60     {
 61         pair<int,int> a=fl(tr[x][0],y);
 62         fa[a.second]=x; tr[x][0]=a.second; up(x); a.second=x; return a;
 63     }else
 64     {
 65         pair<int,int> a=fl(tr[x][1],y-tr[tr[x][0]][2]-1);
 66         fa[a.first]=x; tr[x][1]=a.first; up(x); a.first=x; return a;
 67     }
 68 }
 69 int hb(int x,int y)
 70 {
 71     if(x==0)return y; if(y==0)return x;
 72     down(x); down(y);
 73     if(1ll*rand()*(tr[x][2]+tr[y][2])<1ll*RAND_MAX*tr[x][2]){ int a=hb(tr[x][1],y); fa[a]=x; tr[x][1]=a; up(x); return x; }
 74     int a=hb(x,tr[y][0]); fa[a]=y; tr[y][0]=a; up(y); return y;
 75 }
 76 int find(int x,int y)
 77 {
 78     down(x);
 79     if(tr[tr[x][0]][2]>=y)return find(tr[x][0],y);
 80     if(tr[tr[x][0]][2]+1==y)return x;
 81     return find(tr[x][1],y-tr[tr[x][0]][2]-1);
 82 }
 83 int main()
 84 {
 85     srand(233);
 86     scanf("%d%d",&n,&m); tr[0][4]=-2147483647/3;
 87     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
 88     root=build(1,n);
 89     for(int i=1;i<=m;i++)
 90     {
 91         scanf("%s",s+1);
 92         if(s[1]=='I')
 93         {
 94             scanf("%d%d",&k,&n);
 95             for(int j=1;j<=n;j++)scanf("%d",&a[j]); int x=build(1,n);
 96             pair<int,int> a=fl(root,k); root=hb(hb(a.first,x),a.second);
 97         }else
 98         if(s[1]=='D')
 99         {
100             scanf("%d%d",&j,&k);
101             pair<int,int> a=fl(root,j-1); pair<int,int> b=fl(a.second,k);
102             root=hb(a.first,b.second); del(b.first);
103         }else
104         if((s[1]=='M')and(s[3]=='K'))
105         {
106             scanf("%d%d%d",&j,&k,&l);
107             pair<int,int> a=fl(root,j-1); pair<int,int> b=fl(a.second,k);
108             int x=b.first; tr[x][9]=tr[x][7]=l; tr[x][3]=tr[x][2]*l;
109             if(l>=0)tr[x][4]=tr[x][5]=tr[x][6]=tr[x][3];else tr[x][4]=l,tr[x][5]=tr[x][6]=0;
110             root=hb(hb(a.first,x),b.second);
111         }else
112         if(s[1]=='R')
113         {
114             scanf("%d%d",&j,&k);
115             pair<int,int> a=fl(root,j-1); pair<int,int> b=fl(a.second,k);
116             int x=b.first; tr[x][8]^=1; swap(tr[x][0],tr[x][1]); swap(tr[x][5],tr[x][6]);
117             root=hb(hb(a.first,x),b.second);
118         }else
119         if(s[1]=='G')
120         {
121             scanf("%d%d",&j,&k);
122             pair<int,int> a=fl(root,j-1); pair<int,int> b=fl(a.second,k);
123             int x=b.first; printf("%d
",tr[x][3]); root=hb(hb(a.first,x),b.second);
124         }else printf("%d
",tr[root][4]);
125     }
126 }
C++(非旋转式Treap)
原文地址:https://www.cnblogs.com/GhostReach/p/6258634.html