括号序列的经典做法
把(看成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

 

posted on 2015-01-31 23:19  acphile  阅读(134)  评论(0编辑  收藏  举报