#Codeforces Round #603 (Div. 2) E (线段树)

E. Editor

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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.

扫描二维码关注公众号,回复: 9583206 查看本文章

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 22, and for the bracket sequence (()(()())())(()) — is 33.

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

Input

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

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

Output

In a single line print nn integers, where the ii-th number is:

  • −1−1 if the line received after processing the first ii commands is not valid text,
  • the minimal number of colors in the case of the correct text.

Examples

input

Copy

11
(RaRbR)L)L(

output

Copy

-1 -1 -1 -1 -1 -1 1 1 -1 -1 2 

input

Copy

11
(R)R(R)Ra)c

output

Copy

-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:

  1. (
    ^
  2. (
     ^
  3. (a
     ^
  4. (a
      ^
  5. (ab
      ^
  6. (ab
       ^
  7. (ab)
       ^
  8. (ab)
      ^
  9. (a))
      ^
  10. (a))
     ^
  11. (())
    

题目大意 :

现在要在文本中输入东西,给你一个字符串,当某个字符为 “L” 时,表示鼠标的光标向左移动一个单位(如果已经位于最左边,则不移动),为 “R”时, 表示将光标像右移动一个单位,其他的字符都表示将当前光标指向的字符更改为输入的字符,每次操作都输出一个数,如果括号合法,输出最多有多少层括号的嵌套关系,否则,输出-1

思路 :

线段树维护三个值:区间和,区间最小前缀和,区间最大前缀和。当输入的为左括号时,单点修改 + 1, 为右括号时,单点修改 - 1, 其余的全部置为0, 这样如果区间和不为0,说明左括号与右括号的数量不相等,如果最小前缀和不为0,说明出现右括号在左括号前面的情况,其他情况皆为合法,输出最大前缀和即可,具体区间更新如下

最小前缀和 = min(左区间最小前缀和, 左区间和 + 右区间最小前缀和)

最大前缀和 = max(左区间最大前缀和, 左区间和 + 右区间最大前缀和)

和 = 左区间和 + 右区间和    

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define ls rt << 1
#define rs ls | 1
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define MEM(x, b) memset(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int MOD = 1e9 + 7;
const int MAXN = 1e6 + 100;
const int INF = 0x3f3f3f3f;
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % MOD; b >>= 1; t = (t*t) % MOD; }return r; }

struct Tree
{
	int l, r, ans;
	int lx, rx;
}t[MAXN * 4];
int n, index = 1;
char str[MAXN];
void Build(int rt, int l, int r) {
	t[rt].l = l, t[rt].r = r;
	t[rt].ans = t[rt].lx = t[rt].rx = 0;
	if (l == r) return;
	int mid = (l + r) >> 1;
	Build(ls, l, mid);
	Build(rs, mid + 1, r);
}
void Update(int rt, int x, int pos) {
	if (t[rt].l == t[rt].r) {
		t[rt].ans = pos;
		return;
	}
	int mid = (t[rt].l + t[rt].r) >> 1;
	if (mid < x) Update(rs, x, pos);
	if (mid >= x) Update(ls, x, pos);
	t[rt].lx = min(t[ls].lx, t[ls].ans + t[rs].lx);
	t[rt].rx = max(t[ls].rx, t[ls].ans + t[rs].rx);
	t[rt].ans = t[ls].ans + t[rs].ans;
}

int main()
{
	cin >> n; Build(1, 1, n); getchar();
	sc("%s", str);
	for (int i = 0; i < n; i++) {
		if (str[i] == 'L') index -= (index == 1) ? 0 : 1;
		else if (str[i] == 'R') index++;
		else if (str[i] == '(') Update(1, index, 1);
		else if (str[i] == ')') Update(1, index, -1);
		else Update(1, index, 0);

		if (t[1].ans || t[1].lx) printf("-1 ");
		else printf("%d ", t[1].rx);
	}
	printf("\n");
	return 0;  // 改数组大小!!!
}
发布了213 篇原创文章 · 获赞 264 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43851525/article/details/103342017