题意:有T(T<10)组测试数据,然后有一个数字N(N<100000),接下来的一行里有N个字符,每个字符是'('或')',有三种操作(1)"set l r c",表示将区间[l,r]里的所有元素改变为c,c是'('或')'的其中一种。(2)"reverse l r",表示将区间[l,r]里的'('与')'对调。(3)"query l r",表示查询区间[l,r]是否为一个合法的括号序列。

如果我们视‘(’为-1,而‘)’为1,注意到如果在区间[l,r]里从l出发不断向后扫直到r,同时求和,在这个过程中,如果和的最大值是小于等于0的,并且最后的和是等于0的,那么这个序列是合法的,即输出“YES”。

那么这就要求在线段树的结点中要保存一个sum域和mx域(即最大值),对于操作“set"和操作“reverse"分别有两个延迟操作与之对应,即flag_set和flag_rev。因为操作”reverse“,要求对换1和-1,则为了维护mx域,在线段树的结点中多增加一个域,mi(表示最小值),这样在进行操作”reverse"时,就可以通过一些操作,得到这个区间的mx。

要向下传递延迟操作的时候,要先传递"set"操作的标记,即flag_set,后传递flag_rev。因为对一个区间进行“set"操作的时候,会将之前的”reverse"操作的标记置0(因为之前的“reverse"操作是失效的),如果一个区间同时有flag_set和flag_rev,那么一个是"set"操作先到达这个区间,然后”reverse"操作再到达这个区间。

区间合并的时候,当前区间的mi域是从,左儿子的mi域和左儿子的sum加上右儿子的mi中取最小值,mx域的更新也类似。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=100005;struct node
{int lft,rht;int mi,mx,sum;int flag_set,flag_rev;int mid(){return MID(lft,rht);}int len(){return rht-lft+1;}void init(){ flag_set=flag_rev=mi=mx=sum=0; }void fun(int valu){if(valu){mi=min(valu,valu*len());mx=max(valu,valu*len());sum=valu*len();flag_set=valu; flag_rev=0;}else{sum=-sum; swap(mi,mx); mi=-mi; mx=-mx;flag_rev^=1;}}
};int y[N],n,m;struct Segtree
{node tree[N*4];void down(int ind){if(tree[ind].flag_set){tree[LL(ind)].fun(tree[ind].flag_set);tree[RR(ind)].fun(tree[ind].flag_set);tree[ind].flag_set=0;}if(tree[ind].flag_rev){tree[LL(ind)].fun(0);tree[RR(ind)].fun(0);tree[ind].flag_rev=0;}}void up(int ind){tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;tree[ind].mx=max(tree[LL(ind)].mx,tree[LL(ind)].sum+tree[RR(ind)].mx);tree[ind].mi=min(tree[LL(ind)].mi,tree[LL(ind)].sum+tree[RR(ind)].mi);}void build(int lft,int rht,int ind){tree[ind].lft=lft; tree[ind].rht=rht;tree[ind].init();if(lft==rht) tree[ind].mi=tree[ind].mx=tree[ind].sum=y[lft];else {int mid=tree[ind].mid();build(lft,mid,LL(ind));build(mid+1,rht,RR(ind));up(ind);}}void updata(int st,int ed,int ind,int valu){int lft=tree[ind].lft,rht=tree[ind].rht;if(st<=lft&&rht<=ed) tree[ind].fun(valu);else {down(ind);int mid=tree[ind].mid();if(st<=mid) updata(st,ed,LL(ind),valu);if(ed> mid) updata(st,ed,RR(ind),valu);up(ind);}}void query(int st,int ed,int ind,int &mx,int &sum){int lft=tree[ind].lft,rht=tree[ind].rht;if(st<=lft&&rht<=ed){mx=tree[ind].mx;sum=tree[ind].sum;}else {down(ind);int mid=tree[ind].mid();if(ed<=mid) query(st,ed,LL(ind),mx,sum);else if(st>mid) query(st,ed,RR(ind),mx,sum);else {int mx1,mx2,sum1,sum2;query(st,ed,LL(ind),mx1,sum1);query(st,ed,RR(ind),mx2,sum2);mx=max(mx1,sum1+mx2); sum=sum1+sum2;}up(ind);}}
}seg;
int main()
{int t,t_cnt=0;scanf("%d",&t);while(t--){char str[N];scanf("%d%s",&n,str);for(int i=0;i<n;i++){if(str[i]=='(') y[i]=-1;else y[i]=1;}seg.build(0,n-1,1);scanf("%d",&m);printf("Case %d:\n",++t_cnt);while(m--){int a,b;char cmd[10],chr[10];scanf("%s",cmd);if(cmd[0]=='s'){scanf("%d%d%s",&a,&b,chr);seg.updata(a,b,1,(chr[0]=='('?-1:1));}else if(cmd[0]=='r'){scanf("%d%d",&a,&b);seg.updata(a,b,1,0);}else{int mx,sum;scanf("%d%d",&a,&b);seg.query(a,b,1,mx,sum);if(mx<=0&&sum==0) puts("YES");else puts("NO");}}puts("");}return 0;
}

uestc 1546 Bracket Sequence (成段更新)相关推荐

  1. UESTC 1546 Bracket Sequence

    这题掉了一句话,调了N久~~~ #include <cmath> #include <cstdio> #include <cstdlib> #include < ...

  2. UESTC 1546 Bracket Sequence

    UESTC_1546 这个题目可以借用判断合法括号序列的办法,将'('看作1,将')'看作-1,之后从左向右扫描一个序列并将扫描到的值累加起来,在这个过程中如果任意时刻这些值的和都不小于0,并且最后的 ...

  3. uscao 线段树成段更新操作及Lazy思想(POJ3468解题报告)

    线段树成段更新操作及Lazy思想(POJ3468解题报告) 标签: treequerybuildn2cstruct 2011-11-03 20:37 5756人阅读 评论(0) 收藏 举报  分类: ...

  4. NYOJ 1068 ST(线段树之 成段更新+区间求和)

    ST 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 "麻雀"lengdan用随机数生成了后台数据,但是笨笨的他被妹纸的问题给难住了... 已知len ...

  5. HDU 3974 Assign the task(dfs时间戳+线段树成段更新)

    题意:给定点的上下级关系,规定假设给i分配任务a.那么他的全部下属.都停下手上的工作,開始做a. 操作 T x y 分配x任务y,C x询问x的当前任务: Sample Input 1 5 4 3 3 ...

  6. [HDOJ4027]Can you answer these queries?(线段树,特殊成段更新,成段查询)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 RT,该题要求每次更新是更新所有节点,分别求平方根,查询是求和.昨晚思前想后找有没有一个数学上的 ...

  7. HDOJ 1698 Just a Hook(线段树成段更新)

    题意: 屠夫的钩子区间是1~n,每段可能由铜,银,金组成,价值分别为1,2,3,进行一系列的更新之后,求钩子的总价值. 思路: 线段树的成段更新:要设置一个临时的线段树,每次更新的时候把更新段的值放在 ...

  8. Hdu 1794 【二维成段更新】.cpp

    题意: 给出一个n*n的矩阵和m个数,从m个数中选几个数填入矩阵中值为0的空格中,使矩阵的和最大. 矩阵的和的定义是:所有子矩阵的数的和的和..   思路: 要想矩阵的和最大..应该使m个数中值大的数 ...

  9. 树状数组成段更新模板

    这个成段的编写复杂度很低,不需要加大空间复杂度,便于处理成段加,询问每个位置的值的操作: #include <bits/stdc++.h> using namespace std ; ty ...

最新文章

  1. WinAPI: waveOutGetErrorText - 根据错误号得到错误描述
  2. 树莓派nginx无法安装mysql_树莓派上安装nginx
  3. python函数中可变参数的传递方式是_详解Python函数可变参数定义及其参数传递方式...
  4. Java黑皮书课后题第8章:8.18(打乱行)编写一个方法,使用下面的方法头打乱一个二维int型数组的行。编写一个测试程序,打乱下面的矩阵
  5. lightoj 1004 dp:数字三角形
  6. 挑战程序设计竞赛部分题目选择排序、二分查找找出下标、深度优先算法、求三角形max周长、蚂蚁算法、操作excel
  7. ajax get请求_python测试开发django50.jquery发送Ajax请求(get)
  8. idea 暂存文件或idea切换分支代码不见了
  9. WEB前端常用JavaScript代码整理(二)
  10. 服务器里的文件链接地址怎么写,服务器里的文件链接地址怎么写
  11. 一样的Java,不一样的HDInsight大数据开发体验
  12. php 送货单管理系统,销售送货单管理系统下载
  13. 计算机T层,层螺旋计算机断层摄影术及T磁共振成像对-国家心血管病中心.PDF
  14. 如何清除掉“无法删除”的顽固文件
  15. MVC用filter做权限过滤
  16. 华为智慧屏和鸿蒙系统对比,华为智慧屏s55和v55区别-华为智慧屏s55和v55对比
  17. 使用Linux C 简易实现LS(实现过程)
  18. ​雷军辟谣拒投腾讯阿里:想1000万收购网易,丁磊拒了;Gitlab 禁止使用 Windows | EA周报...
  19. 使用HTML+CSS制作加载动画
  20. [论文总结] 农业工程领域中App和Web相关应用论文笔记

热门文章

  1. 容积卡尔曼(CKF)算法介绍_附例子和代码
  2. 吴忠军 - 素描
  3. 如何在Excel表格中对数据进行批量增加或者减少
  4. 【Rust日报】 2019-04-16 : nude-rs - 高性能黄图检测
  5. 对接腾讯企业邮箱(授权免登,获取未读邮件数量)
  6. 《仓库管理系统》主要功能展示
  7. Vue学习笔记(十一)
  8. 集合框架背后的数据结构
  9. 分享8个有趣的python小玩具
  10. ARM立即寻址中有效立即数的计算