• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
AC_Artist.zig_zag
然而我依然在补题、
博客园    首页    新随笔    联系   管理    订阅  订阅

bzoj 2209 括号匹配

我们把左右括号用-1和1来替代,那么两个不同的括号可以相互抵消,但必须保证是闭合的"()",而不是扩散的")(",这样我们维护一下左右的最小最大值,那么最小值就是孤单左括号的,最大值就是孤单右括号的数目,答案就是(|左小|+右大)/2+(|左小|+右大)%2。注意取反和翻转的不同,需要用不同的方式来维护以上4个值。

brackets
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #define maxn 120000
  7 #define inf 2147483646
  8 using namespace std;
  9 int c[maxn][2];
 10 int fa[maxn],key[maxn],size[maxn],sum[maxn],rev[maxn],opp[maxn],la[maxn],lb[maxn],ra[maxn],rb[maxn];
 11 int n,m,num,rot;
 12 
 13 inline void update(int x)
 14 {
 15         la[x]=min(la[c[x][0]],sum[c[x][0]]+min(key[x],key[x]+la[c[x][1]]));
 16         lb[x]=max(lb[c[x][0]],sum[c[x][0]]+max(key[x],key[x]+lb[c[x][1]]));
 17         ra[x]=min(ra[c[x][1]],sum[c[x][1]]+min(key[x],key[x]+ra[c[x][0]]));
 18         rb[x]=max(rb[c[x][1]],sum[c[x][1]]+max(key[x],key[x]+rb[c[x][0]]));
 19         sum[x]=sum[c[x][0]]+sum[c[x][1]]+key[x];
 20         size[x]=size[c[x][0]]+size[c[x][1]]+1;
 21 }
 22 
 23 inline void reverse(int x)
 24 {
 25         if (!x) return ;
 26         swap(c[x][0],c[x][1]);
 27         swap(la[x],ra[x]);
 28         swap(lb[x],rb[x]);
 29         rev[x]^=1;
 30 }
 31 
 32 inline void oppsite(int x)
 33 {
 34         if (!x) return ;
 35         key[x]=-key[x];
 36         sum[x]=-sum[x];
 37         int tmp;
 38         tmp=la[x]; la[x]=-lb[x]; lb[x]=-tmp;
 39         tmp=ra[x]; ra[x]=-rb[x]; rb[x]=-tmp;    
 40         opp[x]^=1;
 41 }
 42 
 43 inline void down(int x)
 44 {
 45         if (!x) return;
 46         if (rev[x]) 
 47         {
 48                 reverse(c[x][0]);
 49                 reverse(c[x][1]);
 50                 rev[x]=0;
 51         }
 52         if (opp[x])
 53         {
 54                 oppsite(c[x][0]);
 55                 oppsite(c[x][1]);
 56                 opp[x]=0;
 57         }
 58 }
 59 
 60 inline void relax(int x,int rot)
 61 {
 62         if (x!=rot) relax(fa[x],rot);
 63         down(x);
 64 }
 65 
 66 inline void rotate(int x,int &rot)
 67 {
 68         int y=fa[x],z=fa[y];
 69         int p=(c[y][1]==x),q=p^1;
 70         if (y==rot) rot=x;
 71         else if (c[z][0]==y) c[z][0]=x; else c[z][1]=x;
 72         fa[x]=z; fa[y]=x; fa[c[x][q]]=y;
 73         c[y][p]=c[x][q]; c[x][q]=y;
 74         update(y);
 75 }
 76 
 77 inline void splay(int x,int &rot)
 78 {
 79         relax(x,rot);
 80         while (x!=rot)
 81         {
 82                 int y=fa[x],z=fa[y];
 83                 if (y!=rot)
 84                         if ((c[z][0]==y)xor(c[y][0]==x)) rotate(x,rot); else rotate(y,rot);
 85                 rotate(x,rot);
 86         }
 87         update(x);
 88 }
 89 
 90 inline int build(int l,int r)
 91 {
 92         int mid=(l+r)>>1,left=0,right=0;
 93         if (l<mid) left=build(l,mid-1);
 94         if (r>mid) right=build(mid+1,r);
 95         if (left) c[mid][0]=left,fa[left]=mid;
 96         if (right) c[mid][1]=right,fa[right]=mid;
 97         update(mid);
 98         return mid;
 99 }
100 
101 inline int find(int t,int k)
102 {
103         down(t);
104         if (k==size[c[t][0]]+1) return t;
105         if (k<size[c[t][0]]+1) return find(c[t][0],k);
106         if (k>size[c[t][0]]+1) return find(c[t][1],k-size[c[t][0]]-1);
107 }
108         
109 
110 int main()
111 {
112         //freopen("brackets.in","r",stdin);
113         scanf("%d %d\n",&n,&m);
114         char ch;
115         for (int i=2;i<=n+1;i++)
116         {
117                 scanf("%c",&ch);
118                 if (ch=='(') key[i]=1; else key[i]=-1;
119         }
120         rot=build(1,n+2);
121         int sign,x,y;
122         for (int i=1;i<=m;i++)
123         {
124                 scanf("%d %d %d",&sign,&x,&y);
125                 int l=find(rot,x), r=find(rot,y+2);
126                 splay(r,rot);
127                 splay(l,c[rot][0]);
128                 int t=c[l][1];
129                 if (sign==0)
130                 {
131                         int ans=((-la[t])/2)+(rb[t]/2)+((-la[t])%2)+(rb[t]%2);
132                         printf("%d\n",ans);
133                 }
134                 if (sign==1) oppsite(t);
135                 if (sign==2) reverse(t);
136         }
137         return 0;
138 }
139 
140                 

 

AC without art, no better than WA !
posted @ 2013-03-28 22:51  Zig_zag  阅读(405)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3