bzoj2209 [ JSOI2011 ] -- splay

将左括号记为1,右括号记为-1,则一个合法的括号序列满足所有的前缀和非负。

用splay维护。

代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 #define N 100010
  7 inline char nc(){
  8     static char buf[100000],*p1=buf,*p2=buf;
  9     if(p1==p2){
 10         p2=(p1=buf)+fread(buf,1,100000,stdin);
 11         if(p1==p2)return EOF;
 12     }
 13     return *p1++;
 14 }
 15 inline void Read(int& x){
 16     char c=nc();
 17     for(;c<'0'||c>'9';c=nc());
 18     for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
 19 }
 20 char ss[30];
 21 int Len;
 22 inline void Print(int x){
 23     if(x==0)putchar(48);
 24     for(Len=0;x;x/=10)ss[++Len]=x%10;
 25     for(;Len;)putchar(ss[Len--]+48);putchar('\n');
 26 }
 27 int i,j,k,n,m,s[N],ch[N][2],f[N],Rt,c1[N][2],c2[N][2],Sum[N],a[N],x,y,z;
 28 bool r[N],b[N];
 29 char S[N];
 30 inline int Min(int x,int y){
 31     return x<y?x:y;
 32 }
 33 inline int Max(int x,int y){
 34     return x<y?y:x;
 35 }
 36 inline int Abs(int x){
 37     return x<0?-x:x;
 38 }
 39 inline void Pushup(int x){
 40     s[x]=s[ch[x][0]]+s[ch[x][1]]+1;
 41     Sum[x]=Sum[ch[x][0]]+Sum[ch[x][1]]+a[x];
 42     c1[x][0]=Min(Sum[ch[x][0]]+a[x],Min(c1[ch[x][0]][0],Sum[ch[x][0]]+a[x]+c1[ch[x][1]][0]));
 43     c1[x][1]=Max(Sum[ch[x][0]]+a[x],Max(c1[ch[x][0]][1],Sum[ch[x][0]]+a[x]+c1[ch[x][1]][1]));
 44     c2[x][0]=Min(Sum[ch[x][1]]+a[x],Min(c2[ch[x][1]][0],Sum[ch[x][1]]+a[x]+c2[ch[x][0]][0]));
 45     c2[x][1]=Max(Sum[ch[x][1]]+a[x],Max(c2[ch[x][1]][1],Sum[ch[x][1]]+a[x]+c2[ch[x][0]][1]));
 46 }
 47 inline void Update_rev(int x){
 48     if(x==0)return;
 49     swap(c1[x][0],c2[x][0]);
 50     swap(c1[x][1],c2[x][1]);
 51     swap(ch[x][0],ch[x][1]);
 52     r[x]^=1;
 53 }
 54 inline void Update_ops(int x){
 55     if(x==0)return;
 56     a[x]*=-1;Sum[x]*=-1;
 57     swap(c1[x][0],c1[x][1]);
 58     swap(c2[x][0],c2[x][1]);
 59     c1[x][0]*=-1;c1[x][1]*=-1;
 60     c2[x][0]*=-1;c2[x][1]*=-1;
 61     b[x]^=1;
 62 }
 63 inline void Pushdown(int x){
 64     if(r[x]){
 65         Update_rev(ch[x][0]);Update_rev(ch[x][1]);
 66         r[x]=0;
 67     }
 68     if(b[x]){
 69         Update_ops(ch[x][0]);Update_ops(ch[x][1]);
 70         b[x]=0;
 71     }
 72 }
 73 inline void Build(){
 74     ch[Rt=1][1]=2;
 75     for(i=2;i<=n+1;i++){f[i]=i-1;ch[i][1]=i+1;}
 76     f[n+2]=n+1;s[n+2]=1;s[n+1]=2;c1[n+1][0]=c1[n+1][1]=c2[n+1][0]=c2[n+1][1]=a[n];
 77     for(i=n;i>=1;i--)Pushup(i);
 78 }
 79 inline int Get(int x){return ch[f[x]][1]==x;}
 80 inline void Rotate(int x){
 81     bool d=Get(x);int y=f[x];
 82     if(f[y])ch[f[y]][Get(y)]=x;
 83     ch[y][d]=ch[x][d^1];f[ch[y][d]]=y;
 84     f[x]=f[y];f[y]=x;ch[x][d^1]=y;
 85     Pushup(y);
 86 }
 87 inline void P(int x,int y){
 88     if(f[x]!=y)P(f[x],y);
 89     Pushdown(x);
 90 }
 91 inline void Splay(int x,int y){
 92     P(x,y);
 93     for(;f[x]!=y;Rotate(x))
 94     if(f[f[x]]!=y)Rotate(Get(x)==Get(f[x])?f[x]:x);
 95     if(y==0)Rt=x;Pushup(x);
 96 }
 97 inline int Find(int x,int y){
 98     Pushdown(x);
 99     if(s[ch[x][0]]+1==y)return x;
100     if(s[ch[x][0]]>=y)return Find(ch[x][0],y);
101     return Find(ch[x][1],y-s[ch[x][0]]-1); 
102 }
103 inline int Get_result(int x){
104     int t=-c1[x][0];
105     int Res=(t>>1)+t%2;
106     t=(Res<<1)+Sum[x];
107     Res+=Abs(t)>>1;
108     return Res;
109 }
110 inline int Query(int x,int y){
111     int a1=Find(Rt,x-1),a2=Find(Rt,y+1);
112     Splay(a2,0);Splay(a1,Rt);
113     return Get_result(ch[a1][1]);
114 }
115 inline void Update1(int x,int y){
116     int a1=Find(Rt,x-1),a2=Find(Rt,y+1);
117     Splay(a2,0);Splay(a1,Rt);
118     Update_ops(ch[a1][1]);Pushup(a1);Pushup(a2);
119 }
120 inline void Update2(int x,int y){
121     int a1=Find(Rt,x-1),a2=Find(Rt,y+1);
122     Splay(a2,0);Splay(a1,Rt);
123     Update_rev(ch[a1][1]);Pushup(a1);Pushup(a2);
124 }
125 int main(){
126     scanf("%d%d",&n,&m);
127     scanf("%s",S+1);
128     for(i=1;i<=n;i++)
129     if(S[i]=='(')a[i+1]=1;else a[i+1]=-1;
130     Build();
131     while(m--){
132         Read(x);Read(y);Read(z);y++;z++;
133         if(x==0)Print(Query(y,z));else
134         if(x==1)Update1(y,z);else if(x==2)Update2(y,z);
135     }
136     return 0;
137 }
bzoj2209

 

posted @ 2017-03-28 20:40  gjghfd  阅读(192)  评论(0编辑  收藏  举报