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
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
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.
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\n",tr[x][3]); root=hb(hb(a.first,x),b.second); 124 }else printf("%d\n",tr[root][4]); 125 } 126 }