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
*/
拿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
int r=s
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
*/
相关文章推荐
- BZOJ 2209 [Jsoi2011] 括号序列
- 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay
- bzoj 2209: [Jsoi2011]括号序列 splay
- bzoj2209[Jsoi2011] 括号序列
- bzoj2209 [Jsoi2011]括号序列(splay)
- bzoj2209: [Jsoi2011]括号序列
- ●BZOJ 2209 [Jsoi2011]括号序列
- BZOJ 2209: [Jsoi2011]括号序列 [splay 括号]
- [BZOJ2209][[Jsoi2011]括号序列][splay]
- bzoj 2209: [Jsoi2011]括号序列(splay)
- [BZOJ2209][JSOI2011]括号序列(splay)
- 【BZOJ】2209: [Jsoi2011]括号序列(splay)
- BZOJ 2209: [Jsoi2011]括号序列&&BZOJ 2329: [HNOI2011]括号修复
- 【BZOJ2209】括号序列(JSOI2011)-Splay
- BZOJ P2209:[Jsoi2011]括号序列
- [jsoi2011]括号序列
- 【BZOJ-2329&2209】括号修复&括号序列 Splay
- BZOJ2209: [Jsoi2011]括号序列
- bzoj2209括号序列splay
- BZOJ 2209 括号序列(splay)