码迷,mamicode.com
首页 > 其他好文 > 详细

cogs1279 括号修复

时间:2018-01-20 15:09:28      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:uil   getch   就是   blank   event   etc   image   应该   space   

链接

 

时间限制:4 s   内存限制:128 MB

【题目描述】

技术分享图片

注意:以评测系统提供的输入输出文件名为准!

 

 

这个问题乍一看很棘手,因为他询问的东西很奇怪,所以我们考虑如果只有询问操作,我们应该怎么做,我们模拟一个栈来模拟括号匹配的过程,可以发现最终栈中剩下的元素一定是形如)))(((的,这时我们有一个结论 变成合法的最少修改次数为(p/2)+(q/2),注意该式子是要上取整,并且只对于p+q是偶数,奇数并不能实现完全匹配,p和q分别代表无法匹配的)和(的个数,那么问题就转换为了求出序列中无法匹配的)和(的个数,还是很难搞。

我们不妨对原序列做一个转换,我们将所有的)视为-1,将所有的(视为1,那么,p事实上就是这段区间的最小前缀的相反数,而q就是这段区间的最大后缀,因为两者之和是等于区间和的,所以我们只需要维护其中一个即可。假设我们选择维护最大后缀,因为有区间翻转操作,所以我们需要额外维护一个区间最大前缀。

对于区间*-1的情况,我们考虑如何更新最大前缀和最大后缀,最大前缀*-1之后变成了最小前缀,而最小前缀+最大后缀=区间和,所以我们可以以这种方式求出新的最大后缀。

技术分享图片
  1 #include<cstdio>
  2 #define ls ch[x][0]
  3 #define rs ch[x][1]
  4 #define mid ((l+r)>>1)
  5 #define max(a,b) a>b?a:b
  6 using namespace std;
  7 const int inf=1e5+5;
  8 int n,m;
  9 char s[inf];
 10 int rt;
 11 int ch[inf][2],fa[inf],siz[inf];
 12 int v[inf],rev[inf],reset[inf],mul[inf],sum[inf],lmax[inf],rmax[inf];
 13 bool get(int x){
 14     return ch[fa[x]][1]==x;
 15 }
 16 void swap(int &x,int &y){
 17     int tem=x;
 18     x=y;
 19     y=tem;
 20 }
 21 void update(int x){
 22     sum[x]=sum[ls]+sum[rs]+v[x];
 23     siz[x]=siz[ls]+siz[rs]+1;
 24     lmax[x]=max(lmax[ls],sum[ls]+lmax[rs]+v[x]);
 25     rmax[x]=max(rmax[rs],sum[rs]+rmax[ls]+v[x]);
 26 }
 27 void tagdown(int x){
 28     if(reset[x]){
 29         v[x]=reset[x];
 30         sum[ls]=reset[x]*siz[ls];
 31         sum[rs]=reset[x]*siz[rs];
 32         if(reset[x]>0){
 33             lmax[ls]=rmax[ls]=siz[ls];
 34             lmax[rs]=rmax[rs]=siz[rs];
 35         }
 36         else {
 37             lmax[ls]=rmax[ls]=0;
 38             lmax[rs]=rmax[rs]=0;
 39         }
 40         reset[ls]=reset[rs]=reset[x];
 41         rev[x]=0;
 42         mul[x]=1;
 43         reset[x]=0;
 44         return ;
 45     }
 46     if(rev[x]){
 47         swap(ch[ls][0],ch[ls][1]);
 48         swap(ch[rs][0],ch[rs][1]);
 49         swap(lmax[ls],rmax[ls]);
 50         swap(lmax[rs],rmax[rs]);
 51         rev[ls]^=1;rev[rs]^=1;
 52         rev[x]=0;
 53     }
 54     if(mul[x]!=1){
 55         v[x]*=-1;
 56         sum[ls]*=-1;
 57         sum[rs]*=-1;
 58         int tem=lmax[ls];
 59         lmax[ls]=sum[ls]+rmax[ls];
 60         rmax[ls]=sum[ls]+tem;
 61         tem=lmax[rs];
 62         lmax[rs]=sum[rs]+rmax[rs];
 63         rmax[rs]=sum[rs]+tem;
 64         mul[ls]*=-1;mul[rs]*=-1;
 65         reset[ls]*=-1;reset[rs]*=-1;//这里忘记写了 
 66         mul[x]=1;
 67     }
 68 }
 69 void zig(int x){
 70     int old=fa[x],oldf=fa[old];
 71     tagdown(old);
 72     tagdown(x);
 73     bool p=get(x);
 74     if(oldf)ch[oldf][get(old)]=x;
 75     fa[x]=oldf;
 76     fa[ch[old][p]=ch[x][p^1]]=old;
 77     fa[ch[x][p^1]=old]=x;
 78     update(old);
 79     update(x);
 80 }
 81 void splay(int x,int aim=0){
 82     for(int f;(f=fa[x])!=aim;zig(x))
 83         if(fa[f]!=aim)zig(get(x)==get(f)?f:x);
 84     if(!aim)rt=x;
 85 }
 86 int build(int l,int r){
 87     if(l>r)return 0;
 88     if(!rt)rt=mid;
 89     int Ls=build(l,mid-1);
 90     int Rs=build(mid+1,r);
 91     if(Ls)fa[ch[mid][0]=Ls]=mid;
 92     if(Rs)fa[ch[mid][1]=Rs]=mid;
 93     mul[mid]=1;
 94     rev[mid]=0;
 95     reset[mid]=0;
 96     update(mid);
 97     return mid;
 98 }
 99 int kth(int x,int ned){
100     tagdown(x);
101     if(siz[ls]+1==ned)return x;
102     if(ned<siz[ls]+1)return kth(ls,ned);
103     else return kth(rs,ned-siz[ls]-1);
104 }
105 void out(int x){
106     tagdown(x);
107     printf("%d %d %d\n",x,ls,rs);
108     if(ls)out(ls);
109     if(rs)out(rs);
110 }
111 int main()
112 {
113     freopen("brackets.in","r",stdin);
114     freopen("brackets.out","w",stdout);
115 //    freopen("1.txt","r",stdin);
116     scanf("%d%d",&n,&m);
117     scanf("%s",s);
118     for(int i=2;i<=n+1;i++){
119         if(s[i-2]==))v[i]=-1;
120         else v[i]=1;
121     }
122     n+=2;
123     build(1,n);
124     for(int i=1;i<=m;i++){
125         scanf("%s",s);
126         int a,b;
127         scanf("%d%d",&a,&b);
128         a++;b++;
129         a=kth(rt,a-1);
130         b=kth(rt,b+1);
131         splay(a);
132         splay(b,rt);
133         int o=ch[b][0];
134         if(s[0]==R){
135             char c;
136             getchar();
137             c=getchar();
138             if(c==))reset[o]=-1;
139             else reset[o]=1;
140             sum[o]=reset[o]*siz[o];
141             if(reset[o]>0)lmax[o]=rmax[o]=siz[o];
142             else lmax[o]=rmax[o]=0;
143         }
144         if(s[0]==S){
145             rev[o]^=1;
146             swap(ch[o][0],ch[o][1]);
147             swap(lmax[o],rmax[o]);
148         }
149         if(s[0]==I){
150 //            out(rt);
151             mul[o]*=-1;//printf("%d\n",reset[o]);
152             reset[o]*=-1;//这里的操作可以保证tagdown中reset存在的情况下其他操作无需执行 
153             sum[o]*=-1;
154             int tem=lmax[o];
155             lmax[o]=sum[o]+rmax[o];//这个数一定是非负的 
156             rmax[o]=sum[o]+tem;
157         }
158         if(s[0]==Q){
159 //            printf("%d %d %d\n",lmax[o],rmax[o],sum[o]);
160             printf("%d\n",(rmax[o]-sum[o]+1)/2+(rmax[o]+1)/2);//上取整 
161         }
162     }
163     return 0;
164 }
View Code

 

cogs1279 括号修复

标签:uil   getch   就是   blank   event   etc   image   应该   space   

原文地址:https://www.cnblogs.com/Turkeyghb/p/8320487.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!