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

uestc 94(区间更新)

时间:2015-08-20 06:49:03      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:

题意:有一个字符串全部由’(‘和’)’组成,然后有三种操作,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(区间更新)

标签:

原文地址:http://blog.csdn.net/hyczms/article/details/47798321

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