Editor CodeForces - 1263E(线段树)

The development of a text editor is a hard problem. You need to implement an extra module for brackets coloring in text.

Your editor consists of a line with infinite length and cursor, which points to the current character. Please note that it points to only one of the characters (and not between a pair of characters). Thus, it points to an index character. The user can move the cursor left or right one position. If the cursor is already at the first (leftmost) position, then it does not move left.

Initially, the cursor is in the first (leftmost) character.

Also, the user can write a letter or brackets (either (, or )) to the position that the cursor is currently pointing at. A new character always overwrites the old value at that position.

Your editor must check, whether the current line is the correct text. Text is correct if the brackets in them form the correct bracket sequence.

Formally, correct text (CT) must satisfy the following rules:

any line without brackets is CT (the line can contain whitespaces);
If the first character of the string — is (, the last — is ), and all the rest form a CT, then the whole line is a CT;
two consecutively written CT is also CT.
Examples of correct texts: hello(codeforces), round, ((i)(write))edi(tor)s, ( me). Examples of incorrect texts: hello)oops(, round), ((me).

The user uses special commands to work with your editor. Each command has its symbol, which must be written to execute this command.

The correspondence of commands and characters is as follows:

L — move the cursor one character to the left (remains in place if it already points to the first character);
R — move the cursor one character to the right;
any lowercase Latin letter or bracket (( or )) — write the entered character to the position where the cursor is now.
For a complete understanding, take a look at the first example and its illustrations in the note below.

You are given a string containing the characters that the user entered. For the brackets coloring module’s work, after each command you need to:

check if the current text in the editor is a correct text;
if it is, print the least number of colors that required, to color all brackets.
If two pairs of brackets are nested (the first in the second or vice versa), then these pairs of brackets should be painted in different colors. If two pairs of brackets are not nested, then they can be painted in different or the same colors. For example, for the bracket sequence ()(())()() the least number of colors is 2, and for the bracket sequence (()(()())())(()) — is 3.

Write a program that prints the minimal number of colors after processing each command.

Input
The first line contains an integer n (1≤n≤106) — the number of commands.

The second line contains s — a sequence of commands. The string s consists of n characters. It is guaranteed that all characters in a string are valid commands.

Output
In a single line print n integers, where the i-th number is:

−1 if the line received after processing the first i commands is not valid text,
the minimal number of colors in the case of the correct text.
Examples
Input
11
(RaRbR)L)L(
Output
-1 -1 -1 -1 -1 -1 1 1 -1 -1 2
Input
11
®R®Ra)c
Output
-1 -1 1 1 -1 -1 1 1 1 -1 1
Note
In the first example, the text in the editor will take the following form:

(
^
(
^
(a
^
(a
^
(ab
^
(ab
^
(ab)
^
(ab)
^
(a))
^
(a))
^
(())
^

题意:
n个字符的字符串,每个字符代表一个操作。
光标位置一开始到最左边(1)。
如果当前操作是L,那么光标左移一位。
如果当前操作是R,那么光标右移一位。
否则光标位置赋值为当前字符。
求每次操作完成后字符串是否合法(即括号序列是否合法),如果合法,输出最大括号嵌套数,否则输出-1。

思路:
线段树维护区间和,最大值,最小值。
合法序列意味着括号是左右匹配的。那么出现左括号,当前位置之后都+1,出现右括号,当前位置之后都-1。
那么最后一个点的值就是左右括号的数目关系,如果为0就并且序列的最小值为0,就代表是合法的序列,最大嵌套数就是序列最大值。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

const int maxn = 1e6 + 10;
char a[maxn];
int pos[maxn];
vector<int>ans;

struct Tree
{
    int l,r;
    int mx,mi,sum;
    int add;
}t[maxn << 2];

void pushup(int i)
{
    t[i].mx = max(t[i * 2].mx,t[i * 2 + 1].mx);
    t[i].mi = min(t[i * 2].mi,t[i * 2 + 1].mi);
    t[i].sum = t[i * 2].sum + t[i * 2 + 1].sum;
}

void pushdown(int i)
{
    if(t[i].add)
    {
        t[i * 2].sum += t[i].add * (t[i * 2].r - t[i * 2].l + 1);
        t[i * 2 + 1].sum += t[i].add * (t[i * 2 + 1].r - t[i * 2 + 1].l + 1);
        t[i * 2].mx += t[i].add;
        t[i * 2 + 1].mx += t[i].add;
        t[i * 2].mi += t[i].add;
        t[i * 2 + 1].mi += t[i].add;
        t[i * 2].add += t[i].add;
        t[i * 2 + 1].add += t[i].add;
        t[i].add = 0;
    }
}

void build(int i,int l,int r)
{
    t[i].l = l;t[i].r = r;
    t[i].add = t[i].mx = t[i].mi = t[i].sum = 0;
    if(l == r)
    {
        return;
    }
    int m = (l + r) >> 1;
    build(i * 2,l,m);
    build(i * 2 + 1,m + 1,r);
    pushup(i);
}

void update(int i,int x,int y,int v)
{
    if(x <= t[i].l && t[i].r <= y)
    {
        t[i].add += v;
        t[i].sum += v * (t[i].r - t[i].l + 1);
        t[i].mx += v;
        t[i].mi += v;
        return;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    if(x <= m)update(i * 2,x,y,v);
    if(y > m)update(i * 2 + 1,x,y,v);
    pushup(i);
}

Tree query(int i,int x,int y)
{
    if(x <= t[i].l && t[i].r <= y)
    {
        return t[i];
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    Tree t1,t2,t3;
    t1.mi = t2.mi = 1e9;
    t1.mx = t2.mx = 0;
    t1.sum = t2.sum = 0;
    if(x <= m)t1 = query(i * 2,x,y);
    if(y > m)t2 = query(i * 2 + 1,x,y);
    t3.sum = t1.sum + t2.sum;
    t3.mx = max(t1.mx,t2.mx);
    t3.mi = min(t1.mi,t2.mi);
    return t3;
}

int query_mx(int i,int x,int y)
{
    if(x <= t[i].l && t[i].r <= y)
    {
        return t[i].mx;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r);
    int res = 0;
    if(x <= m)res = max(res,query_mx(i * 2,x,y));
    if(y > m)res = max(res,query_mx(i * 2 + 1,x,y));
    return res;
}

int query_mi(int i,int x,int y)
{
    if(x <= t[i].l && t[i].r <= y)
    {
        return t[i].mi;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    int res = 1e9;
    if(x <= m)res = min(res,query_mi(i * 2,x,y));
    if(y > m)res = min(res,query_mi(i * 2 + 1,x,y));
    return res;
}

int query_sum(int i,int x,int y)
{
    if(x <= t[i].l && t[i].r <= y)
    {
        return t[i].sum;
    }
    pushdown(i);
    int m = (t[i].l + t[i].r) >> 1;
    int res = 0;
    if(x <= m)res += query_sum(i * 2,x,y);
    if(y > m)res += query_sum(i * 2 + 1,x,y);
    return res;
}

int main()
{
    int n;scanf("%d",&n);
    scanf("%s",a + 1);
    build(1,1,n);
    int now = 1;
    for(int i = 1;i <= n;i++)
    {
        if(a[i] == 'R')
        {
            now++;
        }
        else if(a[i] == 'L')
        {
            if(now > 1)now--;
        }
        else if(a[i] == ')')
        {
            update(1,now,n,-1 - pos[now]);
            pos[now] = -1;
        }
        else if(a[i] == '(')
        {
            update(1,now,n,1 - pos[now]);
            pos[now] = 1;
        }
        else
        {
            if(pos[now] == 1)
            {
                update(1,now,n,-1);
            }
            else if(pos[now] == -1)
            {
                update(1,now,n,1);
            }
            pos[now] = 0;
        }
        Tree t1 = query(1,1,n);
        Tree t2 = query(1,n,n);
        int mi = t1.mi,sum = t2.sum,mx = t1.mx;
        if(mi == 0 && sum == 0)
        {
            ans.push_back(mx);
        }
        else
        {
            ans.push_back(-1);
        }
    }
    int len = (int)ans.size();
    for(int i = 0;i < len;i++)
    {
        printf("%d ",ans[i]);
    }
    return 0;
}

发布了676 篇原创文章 · 获赞 18 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/104125099