zoukankan      html  css  js  c++  java
  • 【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
    ",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
    ",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 }
  • 相关阅读:
    在数值中加入千位分隔符的方法
    用 Javascript 验证表单(form)中的单选(radio)值
    用 Javascript 验证表单(form)中多选框(checkbox)值
    用 CSS 实现图片替换文字(Image replacement)
    计算机技术分类
    最近好乱acm与数模时间重复了
    memcached Telnet Interface
    event_new
    event_base_loop
    event_base_loop
  • 原文地址:https://www.cnblogs.com/myx12345/p/6294341.html
Copyright © 2011-2022 走看看