您的位置:首页 > Web前端 > JavaScript

BZOJ2209 [Jsoi2011]括号序列

2016-08-23 13:24 495 查看
一个括号序列将合法括号都去掉后将剩下左边一堆右括号和右边一堆左括号,这个括号序列变合法需要的步数就是(左括号数量+1)/2下取整加上(右括号数量+1)/2下取整

拿splay同时维护翻转标记和取反标记,每个点维护4个量表示翻不翻转,取不取反时剩的右括号数量和左括号数量即可

wa了好多好多发最后要了数据结果发现是没弄明白怎么算答案-_-

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 100010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
#define tr son[son[rt][1]][0]
struct data{
int l;
int r;
data(){

}
data(int x){
if(!x){
l=0,r=1;
}else{
l=1,r=0;
}
}
friend data operator +(data x,data y){
data z;
z.l=x.l;
z.r=y.r;
int t=x.r-y.l;
if(t>0){
z.r+=t;
}else{
z.l-=t;
}
return z;
}
};
int fa[MAXN],son[MAXN][2],v[MAXN],siz[MAXN];
data s[MAXN][2][2];
bool rev[MAXN],ch[MAXN];
int rt,tot;
int n,m;
char S[MAXN];
inline void torev(int x){
if(!x){
return ;
}
swap(son[x][0],son[x][1]);
swap(s[x][0][0],s[x][1][0]);
swap(s[x][0][1],s[x][1][1]);
rev[x]^=1;
}
inline void toch(int x){
if(!x){
return ;
}
v[x]^=1;
swap(s[x][0][0],s[x][0][1]);
swap(s[x][1][0],s[x][1][1]);
ch[x]^=1;
}
inline void ud(int x){
siz[x]=siz[son[x][0]]+siz[son[x][1]]+1;
s[x][0][0]=s[x][1][0]=data(v[x]);
s[x][0][1]=s[x][1][1]=data(v[x]^1);
if(son[x][0]){
s[x][0][0]=s[son[x][0]][0][0]+s[x][0][0];
s[x][0][1]=s[son[x][0]][0][1]+s[x][0][1];
s[x][1][0]=s[x][1][0]+s[son[x][0]][1][0];
s[x][1][1]=s[x][1][1]+s[son[x][0]][1][1];
}
if(son[x][1]){
s[x][0][0]=s[x][0][0]+s[son[x][1]][0][0];
s[x][0][1]=s[x][0][1]+s[son[x][1]][0][1];
s[x][1][0]=s[son[x][1]][1][0]+s[x][1][0];
s[x][1][1]=s[son[x][1]][1][1]+s[x][1][1];
}
}
inline void pd(int x){
if(rev[x]){
torev(son[x][0]);
torev(son[x][1]);
rev[x]=0;
}
if(ch[x]){
toch(son[x][0]);
toch(son[x][1]);
ch[x]=0;
}
}
inline void cot(int x,int y,bool z){
if(x){
fa[x]=y;
}
if(y){
son[y][z]=x;
}
}
inline void rot(int x,bool z){
int xx=fa[x],xxx=fa[xx];
cot(son[x][z],xx,z^1);
cot(x,xxx,son[xxx][1]==xx);
cot(xx,x,z);
ud(xx);
}
void splay(int x,int y){
int xx=fa[x],xxx=fa[xx];
while(xx!=y){
if(xxx==y){
rot(x,son[xx][0]==x);
}else{
bool z=son[xxx][0]==xx;
if(son[xx][z]==x){
rot(x,z^1);
rot(x,z);
}else{
rot(xx,z);
rot(x,z);
}
}
xx=fa[x],xxx=fa[xx];
}
ud(x);
if(!y){
rt=x;
}
}
void ins(int &x,int y,int z,int f){
if(!x){
x=++tot;
siz[x]=1;
v[x]=z;
fa[x]=f;
splay(x,0);
return ;
}
if(y<=siz[son[x][0]]){
ins(son[x][0],y,z,x);
}else{
ins(son[x][1],y-siz[son[x][0]]-1,z,x);
}
}
int find(int x,int y){
pd(x);
if(siz[son[x][0]]+1==y){
return x;
}
if(y<=siz[son[x][0]]){
return find(son[x][0],y);
}else{
return find(son[x][1],y-siz[son[x][0]]-1);
}
}
int main(){
int i,o,x,y;
scanf("%d%d%s",&n,&m,S+1);
ins(rt,0,0,0);
for(i=1;i<=n;i++){
ins(rt,i,S[i]==')',0);
}
ins(rt,n+1,1,0);
while(m--){
scanf("%d%d%d",&o,&x,&y);
splay(find(rt,x),0);
splay(find(rt,y+2),rt);
if(o==0){
int l=s[0][0].l;
int r=s[0][0].r;
printf("%d\n",(l+1)/2+(r+1)/2);
}
if(o==1){
toch(tr);
ud(son[rt][1]);
ud(rt);
}
if(o==2){
torev(tr);
ud(son[rt][1]);
ud(rt);
}
}
return 0;
}

/*
220

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: