【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 }

 

posted on 2017-01-17 19:55  myx12345  阅读(198)  评论(0编辑  收藏  举报

导航