zoukankan      html  css  js  c++  java
  • bzoj2209 2329

    括号序列的经典做法
    把(看成1,)看成-1
    匹配的括号序列即任意前缀和都非负
    我们先解决静态的问题,给定一段括号序列求最少修改次数
    我们先找出最大后缀和a和最小前缀和b
    之间一定可以不相交
    显然a+|b|个括号是未匹配的
    显然修改即为(|b|+1) div 2+(a+1) div 2;
    由于序列的变化,我们用splay维护
    由于涉及到括号反转我们还要维护左最大和右最小
    然后就没了
    这个是bzoj2329的代码

      1 var son:array[0..100010,1..2] of longint;
      2     laz,lmax,rmax,lmin,rmin,size,sum,a,fa:array[0..100010] of longint;
      3     cha,rev:array[0..100010] of boolean;
      4     root,i,n,m,x,y,z,w:longint;
      5     ch:char;
      6     s:string;
      7 
      8 function min(a,b:longint):longint;
      9   begin
     10     if a>b then exit(b) else exit(a);
     11   end;
     12 
     13 function max(a,b:longint):longint;
     14   begin
     15     if a>b then exit(a) else exit(b);
     16   end;
     17 
     18 procedure swap(var a,b:longint);
     19   var c:longint;
     20   begin
     21     c:=a;
     22     a:=b;
     23     b:=c;
     24   end;
     25 
     26 procedure get(var a,b:longint);
     27   var c:longint;
     28   begin
     29     c:=a;
     30     a:=-b;
     31     b:=-c;
     32   end;
     33 
     34 procedure update(x:longint);
     35   var l,r:longint;
     36   begin
     37     l:=son[x,1];
     38     r:=son[x,2];
     39     size[x]:=size[l]+size[r]+1;
     40     sum[x]:=sum[l]+sum[r]+a[x];
     41     lmax[x]:=max(lmax[l],sum[l]+a[x]+lmax[r]);
     42     rmax[x]:=max(rmax[r],sum[r]+a[x]+rmax[l]);
     43     lmin[x]:=min(lmin[l],sum[l]+a[x]+lmin[r]);
     44     rmin[x]:=min(rmin[r],sum[r]+a[x]+rmin[l]);
     45   end;
     46 
     47 procedure replace(x,w:longint);
     48   begin
     49     a[x]:=w;
     50     laz[x]:=w;
     51     cha[x]:=false;
     52     if w=-1 then
     53     begin
     54       sum[x]:=-size[x];
     55       lmax[x]:=0;
     56       rmax[x]:=0;
     57       lmin[x]:=sum[x];
     58       rmin[x]:=sum[x];
     59     end
     60     else begin
     61       sum[x]:=size[x];
     62       lmax[x]:=sum[x];
     63       rmax[x]:=sum[x];
     64       lmin[x]:=0;
     65       rmin[x]:=0;
     66     end;
     67   end;
     68 
     69 procedure reverse(x:longint);
     70   begin
     71     swap(son[x,1],son[x,2]);
     72     swap(lmax[x],rmax[x]);
     73     swap(lmin[x],rmin[x]);
     74     rev[x]:=not rev[x];
     75   end;
     76 
     77 procedure change(x:longint);
     78   begin
     79     a[x]:=-a[x];
     80     sum[x]:=-sum[x];
     81     get(lmax[x],lmin[x]);
     82     get(rmax[x],rmin[x]);
     83     cha[x]:=not cha[x];
     84   end;
     85 
     86 procedure push(x:longint);
     87   var l,r:longint;
     88   begin
     89     l:=son[x,1];
     90     r:=son[x,2];
     91     if laz[x]<>0 then
     92     begin
     93       if l<>-1 then replace(l,laz[x]);
     94       if r<>-1 then replace(r,laz[x]);
     95       laz[x]:=0;
     96     end;
     97     if cha[x] then
     98     begin
     99       if l<>-1 then change(l);
    100       if r<>-1 then change(r);
    101       cha[x]:=false;
    102     end;
    103     if rev[x] then
    104     begin
    105       if l<>-1 then reverse(l);
    106       if r<>-1 then reverse(r);
    107       rev[x]:=false;
    108     end;
    109   end;
    110 
    111 function find(k:longint):longint;
    112   var p:longint;
    113   begin
    114     p:=root;
    115     while true do
    116     begin
    117       push(p);
    118       if size[son[p,1]]+1=k then exit(p);
    119       if size[son[p,1]]+1>k then p:=son[p,1]
    120       else begin
    121         k:=k-size[son[p,1]]-1;
    122         p:=son[p,2];
    123       end;
    124     end;
    125   end;
    126 
    127 procedure rotate(x,w:longint);
    128   var y:longint;
    129   begin
    130     y:=fa[x];
    131     push(x);
    132     if fa[y]=-1 then root:=x
    133     else begin
    134       if son[fa[y],1]=y then son[fa[y],1]:=x
    135       else son[fa[y],2]:=x;
    136     end;
    137     fa[x]:=fa[y];
    138     son[y,3-w]:=son[x,w];
    139     if son[x,w]<>-1 then fa[son[x,w]]:=y;
    140     son[x,w]:=y;
    141     fa[y]:=x;
    142     update(y);
    143   end;
    144 
    145 procedure splay(x,f:longint);
    146   var y:longint;
    147   begin
    148     while fa[x]<>f do
    149     begin
    150       y:=fa[x];
    151       if fa[y]=f then
    152       begin
    153         if son[y,1]=x then rotate(x,2)
    154         else rotate(x,1);
    155       end
    156       else begin
    157         if son[fa[y],1]=y then
    158         begin
    159           if son[y,1]=x then rotate(y,2) else rotate(x,1);
    160           rotate(x,2);
    161         end
    162         else begin
    163           if son[y,1]=x then rotate(x,2) else rotate(y,1);
    164           rotate(x,1);
    165         end;
    166       end;
    167     end;
    168     update(x);
    169   end;
    170 
    171 function getrange(x,y:longint):longint;
    172   begin
    173     x:=find(x);
    174     y:=find(y+2);
    175     splay(x,-1);
    176     splay(y,x);
    177     exit(son[y,1]);
    178   end;
    179 
    180 function build(l,r:longint):longint;
    181   var m:longint;
    182   begin
    183     m:=(l+r) shr 1;
    184     build:=m;
    185     if l<=m-1 then
    186     begin
    187       son[m,1]:=build(l,m-1);
    188       fa[son[m,1]]:=m;
    189     end;
    190     if m+1<=r then
    191     begin
    192       son[m,2]:=build(m+1,r);
    193       fa[son[m,2]]:=m;
    194     end;
    195     update(m);
    196   end;
    197 
    198 begin
    199   fillchar(fa,sizeof(fa),255);
    200   fillchar(son,sizeof(son),255);
    201   readln(n,m);
    202   for i:=1 to n do
    203   begin
    204     read(ch);
    205     if ch='(' then a[i]:=1 else a[i]:=-1;
    206   end;
    207   readln;
    208   root:=build(0,n+1);
    209   for i:=1 to m do
    210   begin
    211     read(ch);
    212     s:='';
    213     while ch<>' ' do
    214     begin
    215       s:=s+ch;
    216       read(ch);
    217     end;
    218     read(x,y);
    219     z:=getrange(x,y);
    220     if s='Query' then
    221       writeln((abs(lmin[z])+1) div 2+(rmax[z]+1) div 2)
    222     else if s='Invert' then
    223     begin
    224       if laz[z]=0 then change(z)
    225       else replace(z,-laz[z]);
    226     end
    227     else if s='Swap' then
    228       reverse(z)
    229     else if s='Replace' then
    230     begin
    231       read(ch);
    232       while not((ch='(') or (ch=')')) do read(ch);
    233       if ch='(' then w:=1
    234       else w:=-1;
    235       replace(z,w);
    236     end;
    237     readln;
    238   end;
    239 end.
    View Code
  • 相关阅读:
    oracle中job定时调用存储过程的实例
    oracle recyclebin详解(闪回删除的表)
    启动和禁用约束及删除违反约束的记录
    儒轩画的老鼠
    SQLServer2005重建索引
    [转]你真的了解 console 吗
    [转]C# 理解lock
    [转]大话 程序猿 眼里的 高并发
    莆田系医院名单
    .Net WEB 程序员需要掌握的技能
  • 原文地址:https://www.cnblogs.com/phile/p/4473015.html
Copyright © 2011-2022 走看看