UESTC 1546 Bracket Sequence 线段树成段更新
来源:互联网 发布:tensorflow 遗传算法 编辑:程序博客网 时间:2024/06/05 01:01
题意:给定一个括号序列,可以对它进行set,对把一定范围内的括号变成某一种括号,reverse把左右括号互换,query一定范围内的括号序列是否合法。
做法:一开始的想法,节点记录未匹配的左右括号数,然后进行操作,因为小看了reverse操作(本来以为简单的把左右括号的值改一下就好了,可是...),WA。
然后百度大神,重要发现了一个好算法。
造成一我错 的原因是无法准确找的无法配对的右括号。造成右括号无法配对的原因是,右括号没有足够的最括号,所以,大神把左括号设为1,右括号为-1,这样从左到右计算,节点中值的最小值,这个最小值为0就可能完全匹配,但不一定(只是解决了右括号问题),而且再也不怕reverse了
#include<cstdio> #include<cstring> #define left l,m,x<<1 #define right m+1,r,x<<1|1 const int LMT=100003; int cov[LMT<<2],ox[LMT<<2],sum[LMT<<2],mxsum[LMT<<2],misum[LMT<<2]; char sec[LMT]; inline int max(int a,int b) { return a>b?a:b; } inline int min(int a,int b) { return a<b?a:b; } void ope(int op,int l,int r,int x) { cov[x]=op; mxsum[x]=op==1?r-l+1:0; misum[x]=op==-1?-r+l-1:0; sum[x]=(r-l+1)*op; ox[x]=0; } void fox(int x) { if(cov[x]) { cov[x]*=-1; sum[x]*=-1; ox[x]=0; } else { ox[x]^=1; sum[x]*=-1; } int t=mxsum[x]; mxsum[x]=-misum[x]; misum[x]=-t; } void cut(int l,int r,int x) { int m=(l+r)>>1; if(cov[x]) { ope(cov[x],left); ope(cov[x],right); cov[x]=0; } if(ox[x]) { fox(x<<1);fox(x<<1|1); ox[x]=0; } } void pushup(int x) { sum[x]=sum[x<<1]+sum[x<<1|1]; misum[x]=min(misum[x<<1],sum[x<<1]+misum[x<<1|1]); mxsum[x]=max(mxsum[x<<1],mxsum[x<<1|1]+sum[x<<1]); /******* MAXsum其实只是为了在翻转的时候用翻转的时候,以前不相和的括号就会相合, 这里的maxsum[x<<1|1]+sum[x<<1]提前做了这一步。 ****/ } void update(int op,int L,int R,int l,int r,int x) { if(L<=l&&r<=R) { if(op==-1) { ope(-1,l,r,x); ox[x]=0; } if(op==1) { ope(1,l,r,x); ox[x]=0; } if(op==2)fox(x); return; } cut(l,r,x); int m=(l+r)>>1; if(L<=m)update(op,L,R,left); if(R>m)update(op,L,R,right); pushup(x); } void query(int &mi,int &all,int L,int R,int l,int r,int x) { if(L<=l&&r<=R) { mi=misum[x]; all=sum[x]; return; } cut(l,r,x); int m=(l+r)>>1,mi1=0,mi2=0,al1=0,al2=0; if(L<=m)query(mi1,al1,L,R,left); if(R>m)query(mi2,al2,L,R,right); all=al1+al2; mi=min(mi1,al1+mi2); } void init() { memset(cov,0,sizeof(cov)); memset(ox,0,sizeof(ox)); memset(sum,0,sizeof(sum)); memset(misum,0,sizeof(misum)); memset(mxsum,0,sizeof(mxsum)); } int main(void) { int i,n,T,m,l,r,all,mi,I=1; char ord[10],op; scanf("%d",&T); while(T--) { init(); scanf("%d%s",&n,sec); for(i=0;sec[i];i++) { if(sec[i]=='(') update(1,i,i,0,n-1,1); else update(-1,i,i,0,n-1,1); } scanf("%d",&m); printf("Case %d:\n",I++); while(m--) { scanf("%s",ord); if(!strcmp(ord,"query")) { scanf("%d%d",&l,&r); mi=all=0; query(mi,all,l,r,0,n-1,1); if(mi==0&&all==0)puts("YES"); else puts("NO"); } if(!strcmp(ord,"set")) { scanf("%d%d",&l,&r); op=getchar(); while(op!='('&&op!=')')op=getchar(); if(op=='(')update(1,l,r,0,n-1,1); else update(-1,l,r,0,n-1,1); } if(!strcmp(ord,"reverse")) { scanf("%d%d",&l,&r); update(2,l,r,0,n-1,1); } }printf("\n"); } return 0; }
- UESTC 1546 Bracket Sequence 线段树成段更新
- UESTC 1546 Bracket Sequence(线段树 成段更新)
- UESTC 94 Bracket Sequence(线段树的区间更新)
- UESTC 1546 Bracket Sequence
- UESTC 1546 Bracket Sequence
- UESTC 1546 Bracket Sequence
- uestc 1546 Bracket Sequence(线段树 括号匹配)
- uestc 1546 Bracket Sequence (成段更新)
- UESTC 94 Bracket Sequence
- UESTC 94 Bracket Sequence (线段树 区间修改)
- UESTC 94 - Bracket Sequence(线段树+区间合并)
- UESTC 1546(线段树,成段更新,区间合并)
- hdu3397 Sequence operation(线段树成段更新)
- UESTC 1558 线段树点更新
- UESTC 1057 线段树区间更新
- 【20.95%】【UESTC 94】Bracket Squence
- CF Bracket Sequence
- Longest Regular Bracket Sequence
- HTML嵌套规则
- Qemu compatible kernel configuration
- Linux下USB HID device driver研究
- 杨氏矩阵 Young Tableau
- R语言统计数字频率
- UESTC 1546 Bracket Sequence 线段树成段更新
- 第一次C程序设计上机报告
- VisualSVN-hook检查代码说明
- httpclient4.2.2的几个常用方法,登录之后访问页面问题,下载文件
- 读书小记《headfirst javascript》
- 如何中把excel表中的数据用sql语句导入到数据表中
- android界面View简介及android界面绘制过程
- OANET(五):编译安装Qt-Embedded
- Hdu 1018+1196+2504+2817+1042