bzoj2209 2329
括号序列的经典做法
把(看成1,)看成-1
匹配的括号序列即任意前缀和都非负
我们先解决静态的问题,给定一段括号序列求最少修改次数
我们先找出最大后缀和a和最小前缀和b
之间一定可以不相交
显然a+|b|个括号是未匹配的
显然修改即为(|b|+1) div 2+(a+1) div 2;
由于序列的变化,我们用splay维护
由于涉及到括号反转我们还要维护左最大和右最小
然后就没了
这个是bzoj2329的代码
var son:array[..,..] of longint;
laz,lmax,rmax,lmin,rmin,size,sum,a,fa:array[..] of longint;
cha,rev:array[..] of boolean;
root,i,n,m,x,y,z,w:longint;
ch:char;
s:string; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure get(var a,b:longint);
var c:longint;
begin
c:=a;
a:=-b;
b:=-c;
end; procedure update(x:longint);
var l,r:longint;
begin
l:=son[x,];
r:=son[x,];
size[x]:=size[l]+size[r]+;
sum[x]:=sum[l]+sum[r]+a[x];
lmax[x]:=max(lmax[l],sum[l]+a[x]+lmax[r]);
rmax[x]:=max(rmax[r],sum[r]+a[x]+rmax[l]);
lmin[x]:=min(lmin[l],sum[l]+a[x]+lmin[r]);
rmin[x]:=min(rmin[r],sum[r]+a[x]+rmin[l]);
end; procedure replace(x,w:longint);
begin
a[x]:=w;
laz[x]:=w;
cha[x]:=false;
if w=- then
begin
sum[x]:=-size[x];
lmax[x]:=;
rmax[x]:=;
lmin[x]:=sum[x];
rmin[x]:=sum[x];
end
else begin
sum[x]:=size[x];
lmax[x]:=sum[x];
rmax[x]:=sum[x];
lmin[x]:=;
rmin[x]:=;
end;
end; procedure reverse(x:longint);
begin
swap(son[x,],son[x,]);
swap(lmax[x],rmax[x]);
swap(lmin[x],rmin[x]);
rev[x]:=not rev[x];
end; procedure change(x:longint);
begin
a[x]:=-a[x];
sum[x]:=-sum[x];
get(lmax[x],lmin[x]);
get(rmax[x],rmin[x]);
cha[x]:=not cha[x];
end; procedure push(x:longint);
var l,r:longint;
begin
l:=son[x,];
r:=son[x,];
if laz[x]<> then
begin
if l<>- then replace(l,laz[x]);
if r<>- then replace(r,laz[x]);
laz[x]:=;
end;
if cha[x] then
begin
if l<>- then change(l);
if r<>- then change(r);
cha[x]:=false;
end;
if rev[x] then
begin
if l<>- then reverse(l);
if r<>- then reverse(r);
rev[x]:=false;
end;
end; function find(k:longint):longint;
var p:longint;
begin
p:=root;
while true do
begin
push(p);
if size[son[p,]]+=k then exit(p);
if size[son[p,]]+>k then p:=son[p,]
else begin
k:=k-size[son[p,]]-;
p:=son[p,];
end;
end;
end; procedure rotate(x,w:longint);
var y:longint;
begin
y:=fa[x];
push(x);
if fa[y]=- then root:=x
else begin
if son[fa[y],]=y then son[fa[y],]:=x
else son[fa[y],]:=x;
end;
fa[x]:=fa[y];
son[y,-w]:=son[x,w];
if son[x,w]<>- then fa[son[x,w]]:=y;
son[x,w]:=y;
fa[y]:=x;
update(y);
end; procedure splay(x,f:longint);
var y:longint;
begin
while fa[x]<>f do
begin
y:=fa[x];
if fa[y]=f then
begin
if son[y,]=x then rotate(x,)
else rotate(x,);
end
else begin
if son[fa[y],]=y then
begin
if son[y,]=x then rotate(y,) else rotate(x,);
rotate(x,);
end
else begin
if son[y,]=x then rotate(x,) else rotate(y,);
rotate(x,);
end;
end;
end;
update(x);
end; function getrange(x,y:longint):longint;
begin
x:=find(x);
y:=find(y+);
splay(x,-);
splay(y,x);
exit(son[y,]);
end; function build(l,r:longint):longint;
var m:longint;
begin
m:=(l+r) shr ;
build:=m;
if l<=m- then
begin
son[m,]:=build(l,m-);
fa[son[m,]]:=m;
end;
if m+<=r then
begin
son[m,]:=build(m+,r);
fa[son[m,]]:=m;
end;
update(m);
end; begin
fillchar(fa,sizeof(fa),);
fillchar(son,sizeof(son),);
readln(n,m);
for i:= to n do
begin
read(ch);
if ch='(' then a[i]:= else a[i]:=-;
end;
readln;
root:=build(,n+);
for i:= to m do
begin
read(ch);
s:='';
while ch<>' ' do
begin
s:=s+ch;
read(ch);
end;
read(x,y);
z:=getrange(x,y);
if s='Query' then
writeln((abs(lmin[z])+) div +(rmax[z]+) div )
else if s='Invert' then
begin
if laz[z]= then change(z)
else replace(z,-laz[z]);
end
else if s='Swap' then
reverse(z)
else if s='Replace' then
begin
read(ch);
while not((ch='(') or (ch=')')) do read(ch);
if ch='(' then w:=
else w:=-;
replace(z,w);
end;
readln;
end;
end.
bzoj2209 2329的更多相关文章
- 【BZOJ】2329: [HNOI2011]括号修复(splay+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=2329 和前一题一样,不就多了个replace操作吗.好,就打一下. 然后交上去wa了........ ...
- BZOJ 2329: [HNOI2011]括号修复( splay )
把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和l, 最大后缀和r就可以了..答案就是(l+1)/2+(r+1)/2...用splay维护,O(NlogN). 其实还是挺好写的, ...
- ●BZOJ 2329 [HNOI2011]括号修复.cpp
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2329 题解: Splay 类似 BZOJ 2329 [HNOI2011]括号修复 只是多了一 ...
- BZOJ2209 [Jsoi2011]括号序列 splay
原文链接http://www.cnblogs.com/zhouzhendong/p/8093556.html 题目传送门 - BZOJ2209 题解 我太弱了,调出这题感觉都要吐了. 题解懒得写了. ...
- BZOJ2209: [Jsoi2011]括号序列
传送门 splay练习. 考虑把括号序列转化成类似于区间最大/最小值的情况. 显然我们可以知道括号序列消完的情况肯定是$a$个)和$b$个(,那么把这些括号全部合法化的代价显然就是$\frac{a+1 ...
- [POJ 2329] Nearest number-2
Link: POJ 2329 传送门 Solution: 比较明显的$dp$,但爆搜好像也能过 用多个方向$dp$来解决此题,最后汇总答案即可 一开始我写了4个,但后来发现只要相反的2个方向即可,同时 ...
- [LOJ#2329]「清华集训 2017」我的生命已如风中残烛
[LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...
- [HNOI2011][bzoj 2329] 括号修复 [splay+前缀和]
题面: http://www.lydsy.com/JudgeOnline/problem.php?id=2329 思路: 显然,操作4中输出补全的最小费用是关键 这决定了我们不可能在splay上只维护 ...
- [NewTrain 10][poj 2329]Nearest Number - 2
题面: http://poj.org/problem?id=2329 题解: 这题有很多做法 1. 搜索 复杂度$O(n^4)$ 但是实际上远远达不到这个复杂度 所以可以通过 2. 对于每一个格子,我 ...
随机推荐
- (SQL Analyzer services)定义链接维度
链接文档是在一个 Analysis Services 数据库中存在.但在相同版本和兼容级别的另一个 Analysis Services 数据库中重复使用的一种文档. 链接文档是只读的. 如果您想要修改 ...
- C#获取当前路径,获取当前路径的上一层路径
C#获取当前路径的方法如下: (1)string path1 = System.Environment.CurrentDirectory; //C:\...\bin\Debug -获取和设置当前工作目 ...
- UIView转场动画属性设置
常规动画属性设置(可以同时选择多个进行设置) UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动. UIViewAnimationOptionAllo ...
- OC - 4.OC核心语法
一.点语法 1> 基本使用 点语法本质上是set方法/get方法的调用 2> 使用注意 若出现在赋值操作符的右边,在执行时会转换成get方法 若出现在赋值操作符的左边,在执行时会转换成se ...
- JS Attribute属性操作
Attribute是属性的意思,文章仅对部分兼容IE和FF的Attribute相关的介绍. attributes:获取一个属性作为对象 getAttribute:获取某一个属性的值setAttribu ...
- Codevs 2776 寻找代表元(二分图匹配)
2776 寻找代表元 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题目描述 Description 广州二中苏元实验学校一共有n个社团,分别用1到n编号. 广州二 ...
- PAT_1046 划拳
啦啦啦.今天晚上火车回学校了.= =还是挺舍不得家里的. 题目描述: 划拳是古老中国酒文化的一个有趣的组成部分.酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字.如果谁比划出的数字 ...
- 桶排序之python实现源码
tmp = [] def bucket_sort(old): for i in range(len(old)): tmp.append([]) for i in old: tmp[int( i * l ...
- Python内存管理及引用计数
作为一门动态语言,python很重要的一个概念就是动态类型,即对象的类型和内存占用都是运行时确定的.(Why?)运行时,解释器会根据语法和右操作数来决定新对象的类型.动态类型的实现,是通过引用和对象的 ...
- C语言库函数--操作文件
//C库函数读取文件的代码 I/O缓冲机制 C语言库函数写文件都是写在内存中,然后一次写入磁盘.提高了效率. 读写文件,不对系统进行操作,一般采用C语言库函数.移植可以在任何可以对C支持的操作系统,而 ...