Description:
\quadThe development of a text editor is a hard problem. You need to implement an extra module for brackets coloring in text.
\quadYour 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.
\quadInitially, the cursor is in the first (leftmost) character.
\quadAlso, 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.
\quadYour editor must check, whether the current line is the correct text. Text is correct if the brackets in them form the correct bracket sequence.
\quadFormally, 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.
\quadExamples of correct texts: hello(codeforces), round, ((i)(write))edi(tor)s, ( me). Examples of incorrect texts: hello)oops(, round), ((me).
\quadThe user uses special commands to work with your editor. Each command has its symbol, which must be written to execute this command.
\quadThe 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.
\quadFor a complete understanding, take a look at the first example and its illustrations in the note below.
\quadYou 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.
\quadIf 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 222, and for the bracket sequence (()(()())())(()) — is 333.
\quadWrite a program that prints the minimal number of colors after processing each command.
Input
\quadThe first line contains an integer $n(1≤n≤106)n (1≤n≤10^{6})n(1≤n≤106) — the number of commands.
\quadThe 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
\quadIn 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)R(R)Ra)c(R)R(R)Ra)c(R)R(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))
^
(())
^
\quad题意:给一串指令集,对于指令集中的每一个指令,要求有一个输出,若当前构造的文本内容不能满足每个括号均能一一对应,则输出-1,若能满足每个指令一一对应则输出当前文本最大括号嵌套层数。
\quad维护一颗线段树,线段树维护三个值:
- 区间和(左括号记1,右括号记-1,其他字符记0)
- 区间最大前缀和
- 区间最小前缀和
这三个值的作用:若全区间和不为0,则证明左括号数和右括号数不等,可输出-1.若全区间最小前缀和不为0,则证明有一个右括号没有被左括号对应,可输出-1.而全区间最大前缀和就是我们所要的嵌套层数。
AC代码:
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define pd(n) printf("%d\n", n)
#define pc(n) printf("%c", n)
#define pdd(n,m) printf("%d %d", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n,m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sc(n) scanf("%c",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define mem(a,n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mod(x) ((x)%MOD)
#define gcd(a,b) __gcd(a,b)
#define lowbit(x) (x&-x)
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
inline int read()
{
int ret = 0, sgn = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
sgn = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
ret = ret*10 + ch - '0';
ch = getchar();
}
return ret*sgn;
}
inline void Out(int a) //Êä³öÍâ¹Ò
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
int qpow(int m, int k, int mod)
{
int res = 1, t = m;
while (k)
{
if (k&1)
res = res * t % mod;
t = t * t % mod;
k >>= 1;
}
return res;
}
ll gcd(ll a,ll b)
{
return b==0?a : gcd(b,a%b);
}
ll lcm(ll a,ll b)
{
return a*b/gcd(a,b);
}
using namespace std;
const int maxn =1e6+5;
struct node
{
int l,r,val;
int mi,ma;
} p[maxn<<2];
void pushup(int cur)
{
p[cur].val=p[cur<<1].val+p[cur<<1|1].val;
p[cur].ma=max(p[cur<<1].ma,p[cur<<1].val+p[cur<<1|1].ma);
p[cur].mi=min(p[cur<<1].mi,p[cur<<1].val+p[cur<<1|1].mi);
}
void build(int l,int r,int cur)
{
p[cur].l=l,p[cur].r=r,p[cur].val=p[cur].mi=p[cur].ma=0;
if(l==r)
return;
int mid=(l+r)>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
}
void update(int tar,int val,int cur)
{
int l=p[cur].l,r=p[cur].r;
if(l==r)
{
p[cur].val=val;
return;
}
int mid=(l+r)>>1;
if(tar<=mid)
update(tar,val,cur<<1);
if(tar>mid)
update(tar,val,cur<<1|1);
pushup(cur);
}
string s;
int main()
{
int n;
cin>>n;
cin>>s;
build(1,n,1);
int index=1;
for(int i=0; i<n; i++)
{
switch(s[i])
{
case 'L':
index-=(index==1)?0:1;
break;
case 'R':
index++;
break;
case '(':
update(index,1,1);
break;
case ')':
update(index,-1,1);
break;
default:
update(index,0,1);
break;
}
if(p[1].mi!=0||p[1].val!=0)
cout<<-1;
else
cout<<p[1].ma;
if(i==n-1)
cout<<endl;
else
cout<<" ";
}
}