题意:有一个字符串全部由’(‘和’)’组成。然后有三种操作,query a b输出区间[a,b]字符串的括号序列是否合法。reverse a b把区间[a,b]字符串里全部’(‘替换成’)’,而且把全部’)’替换为’(‘,set a b c,把区间[a,b]的全部字符替换为c。

题解:明显是线段树,为了能够让线段树维护,推断一个字符串是否为合法括号,能够把全部的’(‘替换为-1,’)’替换为1,那么假设这个字符串合法,整个字符串的和应该是0且前缀最大和不能超过0。所以能够在线段树节点加入maxx和sum这两个值维护区间内的前缀最大和和总和。

然后reverse操作时。为了方便计算maxx,节点应该还要维护minn前缀最小和,这样maxx = -minn能够直接计算。还有区间合并时最大和是选左子区间最大和与左子区间总和加上右子区间的最大和中较大的那个。最小和求法同理。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100005;
struct Tree {
int sum, maxx, minn;
int setv, rev;
void f(int val, int left, int right) {
if (!val) {
sum = -sum;
int temp = maxx;
maxx = -minn;
minn = -temp;
rev ^= 1;
}
else {
minn = min(val, val * (right - left + 1));
maxx = max(val, val * (right - left + 1));
sum = val * (right - left + 1);
setv = val;
rev = 0;
}
}
}tree[N << 2];
int n, q, a[N];
char s[N], op[10], c[5]; void pushdown(int k, int left, int right) {
int mid = (left + right) / 2;
if (tree[k].setv) {
tree[k * 2].f(tree[k].setv, left, mid);
tree[k * 2 + 1].f(tree[k].setv, mid + 1, right);
tree[k].setv = 0;
}
if (tree[k].rev) {
tree[k * 2].f(0, left, mid);
tree[k * 2 + 1].f(0, mid + 1, right);
tree[k].rev = 0;
}
} void pushup(int k) {
tree[k].sum = tree[k * 2].sum + tree[k * 2 + 1].sum;
tree[k].maxx = max(tree[k * 2].maxx, tree[k * 2].sum + tree[k * 2 + 1].maxx);
tree[k].minn = min(tree[k * 2].minn, tree[k * 2].sum + tree[k * 2 + 1].minn);
} void build(int k, int left, int right) {
tree[k].setv = tree[k].rev = 0;
if (left == right) {
tree[k].sum = tree[k].maxx = tree[k].minn = a[left];
return;
}
int mid = (left + right) / 2;
build(k * 2, left, mid);
build(k * 2 + 1, mid + 1, right);
pushup(k);
} void modify(int k, int left, int right, int l, int r, int v) {
if (l <= left && right <= r) {
tree[k].f(v, left, right);
return;
}
pushdown(k, left, right);
int mid = (left + right) / 2;
if (l <= mid)
modify(k * 2, left, mid, l, r, v);
if (r > mid)
modify(k * 2 + 1, mid + 1, right, l, r, v);
pushup(k);
} void query(int k, int left, int right, int l, int r, int &sum, int &maxx) {
if (l <= left && right <= r) {
maxx = tree[k].maxx;
sum = tree[k].sum;
return;
}
pushdown(k, left, right);
int mid = (left + right) / 2;
if (r <= mid)
query(k * 2, left, mid, l, r, sum, maxx);
else if (l > mid)
query(k * 2 + 1, mid + 1, right, l, r, sum, maxx);
else {
int sum1, maxx1, sum2, maxx2;
query(k * 2, left, mid, l, mid, sum1, maxx1);
query(k * 2 + 1, mid + 1, right, mid + 1, r, sum2, maxx2);
sum = sum1 + sum2;
maxx = max(maxx1, sum1 + maxx2);
}
pushup(k);
} int main() {
int t, cas = 1;
scanf("%d", &t);
while (t--) {
scanf("%d%s", &n, s + 1);
for (int i = 1; i <= n; i++)
if (s[i] == '(')
a[i] = -1;
else
a[i] = 1;
build(1, 1, n);
printf("Case %d:\n", cas++);
scanf("%d", &q);
int l, r, sum, maxx;
while (q--) {
scanf("%s", op);
if (op[0] == 'q') {
scanf("%d%d", &l, &r);
query(1, 1, n, l + 1, r + 1, sum, maxx);
if (!sum && maxx <= 0)
printf("YES\n");
else
printf("NO\n");
}
else if (op[0] == 's') {
scanf("%d%d%s", &l, &r, c);
if (c[0] == '(')
modify(1, 1, n, l + 1, r + 1, -1);
else
modify(1, 1, n, l + 1, r + 1, 1);
}
else {
scanf("%d%d", &l, &r);
modify(1, 1, n, l + 1, r + 1, 0);
}
}
printf("\n");
}
return 0;
}

uestc 94(区间更新)的更多相关文章

  1. 2015 UESTC 数据结构专题A题 秋实大哥与小朋友 线段树 区间更新,单点查询,离散化

    秋实大哥与小朋友 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 Desc ...

  2. Codeforces Round #419 (Div. 2) A B C 暴力 区间更新技巧 +前缀和 模拟

    A. Karen and Morning time limit per test 2 seconds memory limit per test 512 megabytes input standar ...

  3. CDOJ 1059 秋实大哥与小朋友 STL(set)+离散化+BIT区间更新单点查询

    链接: A - 秋实大哥与小朋友 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%lld & %llu Subm ...

  4. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

  5. hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新

    #1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...

  6. hdu 3397 Sequence operation(线段树:区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...

  7. 【HDU 4614】Vases and Flowers(线段树区间更新懒惰标记)

    题目0到n-1的花瓶,操作1在下标a开始插b朵花,输出始末下标.操作2清空[a,b]的花瓶,求清除的花的数量.线段树懒惰标记来更新区间.操作1,先查询0到a-1有num个空瓶子,然后用线段树的性质,或 ...

  8. HDU 1698 Just a Hook(线段树/区间更新)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description In the g ...

  9. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

随机推荐

  1. split方法切割数组

    指定的字符串按"o"截取 当一个base64需要剪去前面的部分的时候 var params={ "imgJustBase64":this.zheng.split ...

  2. react-native之文件上传下载

    目录 文件上传 1.文件选择 2.文件上传 1.FormData对象包装 2.上传示例 文件下载 最近react-native项目上需要做文件上传下载的功能,由于才接触react-native不久,好 ...

  3. 洛谷1345 [Usaco5.4]奶牛的电信

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  4. [HAOI2016]找相同字符(SAM+DP)

    感觉很水. 因为SAM上一个点的子树大小代表这个点所表示子串的出现次数. 建出广义后缀自动机之后.在\(parent\)树上跑\(DP\),维护\(size[i][1]\),和\(size[i][0] ...

  5. jquery 取页面中ifram中得节点

    <iframe src="html/bai.jsp" frameBorder=0 id=middle name=middle scrolling="yes" ...

  6. [luogu]P4312 [COCI 2009] OTOCI / 极地旅行社(LCT)

    P4312 [COCI 2009] OTOCI / 极地旅行社 题目描述 不久之前,Mirko建立了一个旅行社,名叫"极地之梦".这家旅行社在北极附近购买了N座冰岛,并且提供观光服 ...

  7. 洛谷——P1428 小鱼比可爱

    https://www.luogu.org/problem/show?pid=1428 题目描述 人比人,气死人:鱼比鱼,难死鱼.小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度.参赛的鱼被从 ...

  8. mac和iphone处理视频

    今天在微信上面发现有视频打不开,也无法下载到相册 而到电脑上可以打开 搜了一下,发现格式不对,mp4有很多格式,有的是苹果支持不了的. 要下载一个转换器,我下载了“超级转霸”,然后把视频转成了ipho ...

  9. linux系统调用表(system call table)

    系统调用号 函数名 入口点 源码 0 read sys_read fs/read_write.c 1 write sys_write fs/read_write.c 2 open sys_open f ...

  10. eclipse软件快捷键的使用

    [Ct rl+T] 搜索当前接口的实现类 1. [ALT +/]    此快捷键为用户编辑的好帮手,能为用户提供内容的辅助,不要为记不全方法和属性名称犯愁,当记不全类.方法和属性的名字时,多体验一下[ ...