zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    innerHTML获取标签内容
    images获取所有图片标签
    getElementsByTagName通过标签名获取元素对象集合
    getElementsByName通过标签的name属性来获取元素对象
    getElementsByClassName通过类名获取元素对象集合
    getElementById通过id找到对象
    tp3.2查询指定的字段
    流程控制语句if、else、elif、break、continue
    Python3基础知识之元组、集合、字典
    快速自定义输出格式
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6258634.html
Copyright © 2011-2022 走看看