题意:

输入格式:

解法:
将左括号视为1,右括号视为1,其他字符视为0,
合法括号序列的所有前缀和一定都>=0,且最后=0,
那么问题变为:
可以对括号序列进行单点修改操作,要求判断每次操作之后是否是合法括号序列.
同时求出最大嵌套次数.
因为有序列修改操作,所以上线段树,
每个节点记录前缀和,维护前缀和最小值就可以判断是否合法.
最大嵌套次数其实就是所有前缀和中的最大值,因此再维护一个最大值.
判断最后是否=0,直接用区间和就行了,
综上:
1.区间和
2.前缀最大值
3.前缀最小值
维护前缀最大值和最小值有一些细节,详见代码中的pushup
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=2e6+5;
struct Node{
int a[maxm<<2];
int ma[maxm<<2];
int mi[maxm<<2];
void pushup(int node){
a[node]=a[node*2]+a[node*2+1];
mi[node]=min(mi[node*2],mi[node*2+1]+a[node*2]);
ma[node]=max(ma[node*2],ma[node*2+1]+a[node*2]);
}
void update(int x,int val,int l,int r,int node){
if(l==r){
mi[node]=ma[node]=a[node]=val;
return ;
}
int mid=(l+r)/2;
if(x<=mid)update(x,val,l,mid,node*2);
else update(x,val,mid+1,r,node*2+1);
pushup(node);
}
}t;
char s[maxm];
signed main(){
int n;cin>>n;
int cur=1;
scanf("%s",s+1);
for(int i=1;i<=n;i++){
if(s[i]=='L')cur=max(1,cur-1);
else if(s[i]=='R')cur++;
else if(s[i]=='('||s[i]==')'){
if(s[i]=='('){
t.update(cur,1,1,n,1);
}else{
t.update(cur,-1,1,n,1);
}
}else{
t.update(cur,0,1,n,1);
}
if(t.mi[1]<0||t.a[1]!=0){
cout<<-1<<' ';
}else{
cout<<t.ma[1]<<' ';
}
}
return 0;
}