Codeforces Round #603 (Div. 2) E - Editor(线段树,括号序列)

🦋 🦋 🦋
不知不觉已经咕了。。七八十来场CF了,,为什么一到考试周比赛这么多啊,雷菊苣上蓝了(在我咕掉的其中一场。。羡慕)
自己已经这么菜了இ௰இ,考完试要抓紧时间了

题意:一串操作序列,问你每个操作之后是否是合法括号,以及括号的最大嵌套深度;

学到了处理括号序列合法性的新方法:
1.将左括号视为1,右括号视为-1
2.前缀和需要满足任意前缀和大于等于0
3.整个序列和等于0
4.此时嵌套最大深度即为前缀和最大值

然后就是更新的时候判断一下这里以前是什么符号,线段树维护一下前缀和最大最小值,用一个sum记录下总和

#define lson o << 1
#define rson o << 1 | 1
#define mid (l + r) / 2
struct Tree
{
    int add,minv,maxv;
} tree[MAXN<<2];
int n, m;
char s[MAXN], res[MAXN];
void pushup(int o)
{
    tree[o].maxv = max(tree[lson].maxv, tree[rson].maxv);
    tree[o].minv = min(tree[lson].minv, tree[rson].minv);
}
void pushdown(int o)
{
    if (tree[o].add)
    {
        tree[lson].add += tree[o].add,tree[rson].add += tree[o].add;
        tree[lson].maxv += tree[o].add,tree[rson].maxv += tree[o].add;
        tree[lson].minv += tree[o].add,tree[rson].minv += tree[o].add;
        tree[o].add = 0;
    }
}
void add(int o, int l, int r, int from, int to, int v)//区间修改
{
    if (l >= from && r <= to)
    {
        tree[o].add += v, tree[o].maxv += v,tree[o].minv += v;
        return;
    }
    pushdown(o);
    if (from <= mid) add(lson, l, mid, from, to, v);
    if (to > mid) add(rson, mid + 1, r, from, to, v);
    pushup(o);
}
int ask(int o, int l, int r, int p)//单点查询
{
    if (l == r) return tree[o].maxv;
    pushdown(o);
    if (p <= mid) return ask(lson, l, mid, p);
    else return ask(rson, mid + 1, r, p);
}
int main()
{
    scanf("%d", &n);
    scanf("%s", s + 1);
    int now = 1;
    for (int i = 1; i <= n; i++)
    {
        if (s[i] == 'L') now--;
        else if (s[i] == 'R') now++;
        else if (s[i] == '(')
        {
            if (res[now] == ')') add(1, 1, n, now, n, 2);
            else if (res[now] != '(') add(1, 1, n, now, n, 1);
            res[now] = '(';
        }
        else if (s[i] == ')')
        {
            if (res[now] == '(') add(1, 1, n, now, n, -2);
            else if (res[now] != ')') add(1, 1, n, now, n, -1);
            res[now] = ')';
        }
        else
        {
            if (res[now] == '(') add(1, 1, n, now, n, -1);
            else if (res[now] == ')') add(1, 1, n, now, n, 1);
            res[now] = s[i];
        }
        now = max(now, 1);
        if (tree[1].minv >= 0 && ask(1, 1, n, n) == 0) printf("%d ", tree[1].maxv);
        else printf("-1 ");
    }
    printf("\n");
    return 0;
}
posted @ 2019-12-18 19:17  Herlo  阅读(307)  评论(0)    收藏  举报