bzoj2209 [ JSOI2011 ] -- splay

来源:互联网 发布:淘宝 台湾省 编辑:程序博客网 时间:2024/05/22 04:30
将左括号记为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));else134         if(x==1)Update1(y,z);else if(x==2)Update2(y,z);135     }136     return 0;137 }
bzoj2209