【BZOJ1500】维修数列(splay)
题意:
输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
思路:集大成的splay模板,写完就去学LCT了
注意可能会爆INT64,改了好久,我也不知道c++为什么不开long long能过
这题卡内存,需要数组垃圾回收
1 const oo=1000000000; 2 3 var t:array[0..510000,0..1]of longint; 4 sum,lx,rx,mx:array[0..510000]of int64; 5 tag,rev,a,b,fa,id,d,size:array[0..510000]of longint; 6 q:array[0..510000]of longint; 7 n,m,i,j,k,x,f,root,cnt,head,tail,s:longint; 8 ch:ansistring; 9 10 function max(x,y:int64):int64; 11 begin 12 if x>y then exit(x); 13 exit(y); 14 end; 15 16 procedure swap(var x,y:int64); 17 var t:int64; 18 begin 19 t:=x; x:=y; y:=t; 20 end; 21 22 procedure pushup(x:longint); 23 var l,r:longint; 24 begin 25 l:=t[x,0]; r:=t[x,1]; 26 sum[x]:=sum[l]+sum[r]+b[x]; 27 size[x]:=size[l]+size[r]+1; 28 mx[x]:=max(mx[l],mx[r]); 29 mx[x]:=max(mx[x],rx[l]+lx[r]+b[x]); 30 lx[x]:=max(lx[l],sum[l]+b[x]+lx[r]); 31 rx[x]:=max(rx[r],sum[r]+b[x]+rx[l]); 32 end; 33 34 procedure pushdown(x:longint); 35 var l,r,tmp:longint; 36 begin 37 l:=t[x,0]; r:=t[x,1]; 38 if tag[x]>0 then 39 begin 40 rev[x]:=0; tag[x]:=0; 41 if l>0 then 42 begin 43 tag[l]:=1; b[l]:=b[x]; sum[l]:=b[x]*size[l]; 44 end; 45 if r>0 then 46 begin 47 tag[r]:=1; b[r]:=b[x]; sum[r]:=b[x]*size[r]; 48 end; 49 if b[x]>=0 then 50 begin 51 if l>0 then 52 begin 53 lx[l]:=sum[l]; rx[l]:=sum[l]; mx[l]:=sum[l]; 54 end; 55 if r>0 then 56 begin 57 lx[r]:=sum[r]; rx[r]:=sum[r]; mx[r]:=sum[r]; 58 end; 59 end 60 else 61 begin 62 if l>0 then 63 begin 64 lx[l]:=0; rx[l]:=0; mx[l]:=b[x]; 65 end; 66 if r>0 then 67 begin 68 lx[r]:=0; rx[r]:=0; mx[r]:=b[x]; 69 end; 70 end; 71 end; 72 if rev[x]>0 then 73 begin 74 rev[x]:=rev[x] xor 1; rev[l]:=rev[l] xor 1; rev[r]:=rev[r] xor 1; 75 //tmp:=lx[l]; lx[l]:=rx[l]; rx[l]:=tmp; 76 //tmp:=lx[r]; lx[r]:=rx[r]; rx[r]:=tmp; 77 tmp:=t[l,0]; t[l,0]:=t[l,1]; t[l,1]:=tmp; 78 tmp:=t[r,0]; t[r,0]:=t[r,1]; t[r,1]:=tmp; 79 80 swap(lx[l],rx[l]); swap(lx[r],rx[r]); 81 // swap(t[l,0],t[l,1]); swap(t[r,0],t[r,1]); 82 end; 83 end; 84 85 procedure rotate(x:longint;var k:longint); 86 var y,z,l,r:longint; 87 begin 88 y:=fa[x]; z:=fa[y]; 89 if t[y,0]=x then l:=0 90 else l:=1; 91 r:=l xor 1; 92 if y<>k then 93 begin 94 if t[z,0]=y then t[z,0]:=x 95 else t[z,1]:=x; 96 end 97 else k:=x; 98 fa[t[x,r]]:=y; fa[x]:=z; fa[y]:=x; 99 t[y,l]:=t[x,r]; t[x,r]:=y; 100 pushup(y); 101 pushup(x); 102 end; 103 104 procedure splay(x:longint;var k:longint); 105 var y,z:longint; 106 begin 107 while x<>k do 108 begin 109 y:=fa[x]; z:=fa[y]; 110 if y<>k then 111 begin 112 if (t[y,0]=x)xor(t[z,0]=y) then rotate(x,k) 113 else rotate(y,k); 114 end 115 else k:=x; 116 rotate(x,k); 117 end; 118 end; 119 120 procedure build(l,r,x:longint); 121 var mid,now,last:longint; 122 begin 123 if l>r then exit; 124 mid:=(l+r)>>1; now:=id[mid]; last:=id[x]; 125 if l=r then 126 begin 127 sum[now]:=a[l]; size[now]:=1; 128 tag[now]:=0; rev[now]:=0; 129 if a[l]>=0 then 130 begin 131 lx[now]:=a[l]; rx[now]:=a[l]; mx[now]:=a[l]; 132 end 133 else 134 begin 135 lx[now]:=0; rx[now]:=0; mx[now]:=a[l]; 136 end; 137 end 138 else 139 begin 140 build(l,mid-1,mid); 141 build(mid+1,r,mid); 142 end; 143 b[now]:=a[mid]; fa[now]:=last; 144 pushup(now); 145 if mid>=x then t[last,1]:=now 146 else t[last,0]:=now; 147 end; 148 149 function find(x,k:longint):longint; 150 var l,r:longint; 151 begin 152 pushdown(x); 153 l:=t[x,0]; r:=t[x,1]; 154 if size[l]+1=k then exit(x); 155 if size[l]+1>k then exit(find(l,k)) 156 else exit(find(r,k-size[l]-1)); 157 end; 158 159 procedure clear(x:longint); 160 var l,r:longint; 161 begin 162 if x=0 then exit; 163 l:=t[x,0]; r:=t[x,1]; 164 clear(l); clear(r); 165 inc(tail); q[tail mod 510000]:=x; //队列,记录以前用过但现在已经被删除,可以使用的编号
166 fa[x]:=0; t[x,0]:=0; t[x,1]:=0; 167 tag[x]:=0; rev[x]:=0; 168 end; 169 170 function split(k,tot:longint):longint; 171 var x,y:longint; 172 begin 173 x:=find(root,k); y:=find(root,k+tot+1); 174 splay(x,root); splay(y,t[x,1]); 175 exit(t[y,0]); 176 end; 177 178 procedure query(k,tot:longint); 179 var x:longint; 180 begin 181 x:=split(k,tot); 182 writeln(sum[x]); 183 end; 184 185 procedure del(k,tot:longint); 186 var x,y:longint; 187 begin 188 x:=split(k,tot); y:=fa[x]; 189 clear(x); t[y,0]:=0; 190 pushup(y); 191 pushup(fa[y]); 192 end; 193 194 procedure change(k,tot,v:longint); 195 var x,y:longint; 196 begin 197 x:=split(k,tot); y:=fa[x]; 198 b[x]:=v; tag[x]:=1; sum[x]:=size[x]*v; 199 if v>=0 then 200 begin 201 lx[x]:=sum[x]; rx[x]:=sum[x]; mx[x]:=sum[x]; 202 end 203 else 204 begin 205 lx[x]:=0; rx[x]:=0; mx[x]:=v; 206 end; 207 pushup(y); 208 pushup(fa[y]); 209 end; 210 211 procedure rever(k,tot:longint); 212 var x,y,tmp:longint; 213 begin 214 x:=split(k,tot); y:=fa[x]; 215 if tag[x]=0 then 216 begin 217 rev[x]:=rev[x] xor 1; 218 tmp:=t[x,0]; t[x,0]:=t[x,1]; t[x,1]:=tmp; 219 // swap(t[x,0],t[x,1]); 220 swap(lx[x],rx[x]); 221 pushup(y); 222 pushup(fa[y]); 223 end; 224 end; 225 226 procedure ins(k,tot:longint); 227 var x,y,z,i:longint; 228 begin 229 for i:=1 to tot do 230 if tail>=head then begin id[i]:=q[head mod 510000]; inc(head); end //垃圾回收 231 else begin inc(cnt); id[i]:=cnt; end; 232 build(1,tot,0); z:=id[(tot+1)>>1]; 233 x:=find(root,k+1); y:=find(root,k+2); 234 splay(x,root); splay(y,t[x,1]); 235 fa[z]:=y; t[y,0]:=z; 236 pushup(y); 237 pushup(x); 238 end; 239 240 begin 241 242 readln(n,m); 243 head:=1; tail:=0; 244 mx[0]:=-oo; a[1]:=-oo; a[n+2]:=-oo; 245 for i:=2 to n+1 do read(a[i]); 246 readln; 247 for i:=1 to n+2 do id[i]:=i; 248 build(1,n+2,0); 249 root:=(n+3)>>1; cnt:=n+2; 250 for i:=1 to m do 251 begin 252 for j:=1 to 5 do d[j]:=0; 253 readln(ch); s:=0; 254 k:=length(ch); f:=1; x:=0; 255 for j:=1 to k do 256 begin 257 if (ch[j]>='A')and(ch[j]<='Z')or((ch[j]='-')and(s=0)) then continue; 258 if ch[j]=' ' then 259 begin 260 if s>0 then d[s]:=f*x; 261 inc(s); 262 x:=0; f:=1; 263 continue; 264 end; 265 if ch[j]='-' then 266 begin 267 f:=-1; continue; 268 end; 269 x:=x*10+ord(ch[j])-ord('0'); 270 end; 271 d[s]:=f*x; 272 ch:=copy(ch,1,3); 273 if ch='INS' then 274 begin 275 for j:=1 to d[2] do a[j]:=d[j+2]; 276 ins(d[1],d[2]); 277 end; 278 if ch='DEL' then del(d[1],d[2]); 279 if ch='MAK' then change(d[1],d[2],d[3]); 280 if ch='REV' then rever(d[1],d[2]); 281 if ch='GET' then 282 if d[2]=0 then writeln(0) 283 else query(d[1],d[2]); 284 if ch='MAX' then writeln(mx[root]); 285 end; 286 287 end.
UPD(2018.9.17):C++
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define N 1100000 21 #define MOD 1000000007 22 #define eps 1e-8 23 #define pi acos(-1) 24 #define oo 1e9 25 26 int a[N],id[N],fa[N],t[N][2],sum[N],size[N],v[N],mx[N],lx[N],rx[N], 27 tag[N],rev[N],n,m,root,cnt; 28 queue<int> q; 29 30 int read() 31 { 32 int v=0,f=1; 33 char c=getchar(); 34 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 35 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 36 return v*f; 37 } 38 39 void pushup(int x) 40 { 41 int l=t[x][0]; 42 int r=t[x][1]; 43 sum[x]=sum[l]+sum[r]+v[x]; 44 size[x]=size[l]+size[r]+1; 45 mx[x]=max(mx[l],mx[r]); 46 mx[x]=max(mx[x],rx[l]+v[x]+lx[r]); 47 lx[x]=max(lx[l],sum[l]+v[x]+lx[r]); 48 rx[x]=max(rx[r],sum[r]+v[x]+rx[l]); 49 } 50 51 void pushdown(int x) 52 { 53 int l=t[x][0]; 54 int r=t[x][1]; 55 if(tag[x]) 56 { 57 rev[x]=tag[x]=0; 58 if(l){tag[l]=1; v[l]=v[x]; sum[l]=v[x]*size[l];} 59 if(r){tag[r]=1; v[r]=v[x]; sum[r]=v[x]*size[r];} 60 if(v[x]>=0) 61 { 62 if(l) lx[l]=rx[l]=mx[l]=sum[l]; 63 if(r) lx[r]=rx[r]=mx[r]=sum[r]; 64 } 65 else 66 { 67 if(l){lx[l]=rx[l]=0; mx[l]=v[x];} 68 if(r){lx[r]=rx[r]=0; mx[r]=v[x];} 69 } 70 } 71 if(rev[x]) 72 { 73 rev[x]^=1; rev[l]^=1; rev[r]^=1; 74 swap(lx[l],rx[l]); 75 swap(lx[r],rx[r]); 76 swap(t[l][0],t[l][1]); 77 swap(t[r][0],t[r][1]); 78 } 79 } 80 81 void rotate(int x,int &k) 82 { 83 int y=fa[x]; 84 int z=fa[y]; 85 int l; 86 if(t[y][0]==x) l=0; 87 else l=1; 88 int r=l^1; 89 if(y!=k) 90 { 91 if(t[z][0]==y) t[z][0]=x; 92 else t[z][1]=x; 93 } 94 else k=x; 95 fa[t[x][r]]=y; fa[x]=z; fa[y]=x; 96 t[y][l]=t[x][r]; t[x][r]=y; 97 pushup(y); 98 pushup(x); 99 } 100 101 void splay(int x,int &k) 102 { 103 while(x!=k) 104 { 105 int y=fa[x]; 106 int z=fa[y]; 107 if(y!=k) 108 { 109 if(t[y][0]==x^t[z][0]==y) rotate(x,k); 110 else rotate(y,k); 111 } 112 else k=x; 113 rotate(x,k); 114 } 115 } 116 117 int find(int x,int rank) 118 { 119 pushdown(x); 120 int l=t[x][0]; 121 int r=t[x][1]; 122 if(size[l]+1==rank) return x; 123 if(size[l]>=rank) return find(l,rank); 124 return find(r,rank-size[l]-1); 125 } 126 127 void rec(int x) 128 { 129 if(!x) return; 130 int l=t[x][0]; 131 int r=t[x][1]; 132 rec(l); 133 rec(r); 134 q.push(x); 135 fa[x]=t[x][0]=t[x][1]=tag[x]=rev[x]=0; 136 } 137 138 int split(int k,int tot) 139 { 140 int x=find(root,k); 141 int y=find(root,k+tot+1); 142 splay(x,root); 143 splay(y,t[x][1]); 144 return t[y][0]; 145 } 146 147 void query(int k,int tot) 148 { 149 int x=split(k,tot); 150 printf("%d\n",sum[x]); 151 } 152 153 void update(int k,int tot,int val) 154 { 155 int x=split(k,tot); 156 int y=fa[x]; 157 v[x]=val; tag[x]=1; sum[x]=size[x]*val; 158 if(val>=0) lx[x]=rx[x]=mx[x]=sum[x]; 159 else{lx[x]=rx[x]=0; mx[x]=val;} 160 pushup(y); 161 pushup(fa[y]); 162 } 163 164 void rever(int k,int tot) 165 { 166 int x=split(k,tot); 167 int y=fa[x]; 168 if(!tag[x]) 169 { 170 rev[x]^=1; 171 swap(t[x][0],t[x][1]); 172 swap(lx[x],rx[x]); 173 pushup(y); 174 pushup(fa[y]); 175 } 176 } 177 178 void Delete(int k,int tot) 179 { 180 int x=split(k,tot); 181 int y=fa[x]; 182 rec(x); 183 t[y][0]=0; 184 pushup(y); 185 pushup(fa[y]); 186 } 187 188 void build(int l,int r,int p) 189 { 190 if(l>r) return; 191 int mid=(l+r)>>1; 192 int now=id[mid]; 193 int last=id[p]; 194 if(l==r) 195 { 196 sum[now]=a[l]; 197 size[now]=1; 198 tag[now]=rev[now]=0; 199 if(a[l]>=0) lx[now]=rx[now]=mx[now]=a[l]; 200 else{lx[now]=rx[now]=0; mx[now]=a[l];} 201 } 202 else 203 { 204 build(l,mid-1,mid); 205 build(mid+1,r,mid); 206 } 207 v[now]=a[mid]; 208 fa[now]=last; 209 pushup(now); 210 t[last][mid>=p]=now; 211 } 212 213 void Insert(int k,int tot) 214 { 215 for(int i=1;i<=tot;i++) a[i]=read(); 216 for(int i=1;i<=tot;i++) 217 if(!q.empty()){id[i]=q.front(); q.pop();} 218 else id[i]=++cnt; 219 build(1,tot,0); 220 int z=id[(tot+1)>>1]; 221 int x=find(root,k+1); 222 int y=find(root,k+2); 223 splay(x,root); 224 splay(y,t[x][1]); 225 fa[z]=y; 226 t[y][0]=z; 227 pushup(y); 228 pushup(x); 229 } 230 231 int main() 232 { 233 //freopen("bzoj1500.in","r",stdin); 234 //freopen("bzoj1500.out","w",stdout); 235 n=read(); 236 m=read(); 237 mx[0]=a[1]=a[n+2]=-oo; 238 for(int i=2;i<=n+1;i++) a[i]=read(); 239 for(int i=1;i<=n+2;i++) id[i]=i; 240 build(1,n+2,0); 241 root=(n+3)>>1; 242 cnt=n+2; 243 int x,y,z; 244 char ch[10]; 245 while(m--) 246 { 247 scanf("%s",ch); 248 if(ch[0]!='M'||ch[2]!='X') scanf("%d%d",&x,&y); 249 if(ch[0]=='I') Insert(x,y); 250 if(ch[0]=='D') Delete(x,y); 251 if(ch[0]=='M') 252 { 253 if(ch[2]=='X') printf("%d\n",mx[root]); 254 else 255 { 256 z=read(); 257 update(x,y,z); 258 } 259 } 260 if(ch[0]=='R') rever(x,y); 261 if(ch[0]=='G') query(x,y); 262 } 263 return 0; 264 }
null