E. Editor

我们把“(”用1表示,“)”用-1表示,其余字母用0表示,这样形成的一个数组,我们求出它的前缀和sum[],只有当\(sum[n]==0\)\(min(sum[])==0\)中的时候,才表示括号正好匹配,且最大嵌套数为\(max(sum[])\)

对于一个数组来说,要实现多次单点查询、区间修改、区间求极值这三个功能的话,我们可以利用线段树来提高其效率。

算法的板子没事多敲敲,不然很容易生疏....

代码:

// Created by CAD on 2019/12/3.
#include <bits/stdc++.h>

#define inf 0x3f3f3f3f
#define lson (p<<1)
#define rson (p<<1|1)
using namespace std;

const int maxn=1e6+10;
struct node{
    int maxx=0,minn=0;
    int sum=0;
}d[maxn<<2];
int a[maxn],laz[maxn<<2];

void pushdown(int s,int t,int p)
{
    int m=(s+t)>>1;
    d[lson].sum+=laz[p]*(m-s+1),d[rson].sum+=laz[p]*(t-m);
    d[lson].maxx+=laz[p],d[rson].maxx+=laz[p];
    d[lson].minn+=laz[p],d[rson].minn+=laz[p];
    laz[lson]+=laz[p],laz[rson]+=laz[p];
    laz[p]=0;
}
void update(int l,int r,int c,int s,int t,int p)
{
    if(l<=s&&t<=r)
    {
        d[p].sum+=(t-s+1)*c,laz[p]+=c;
        d[p].minn+=c,d[p].maxx+=c;
        return ;
    }
    int m=(s+t)>>1;
    if(laz[p]) pushdown(s,t,p);
    if(l<=m) update(l,r,c,s,m,lson);
    if(r>m) update(l,r,c,m+1,t,rson);
    d[p].maxx=max(d[lson].maxx,d[rson].maxx);
    d[p].minn=min(d[lson].minn,d[rson].minn);
    d[p].sum=d[lson].sum+d[rson].sum;
}
int que_min(int l,int r,int s,int t,int p)
{
    if(l<=s&&t<=r) return d[p].minn;
    int m=(s+t)>>1;
    if(laz[p]) pushdown(s,t,p);
    int minn=inf;
    if(l<=m) minn=min(que_min(l,r,s,m,lson),minn);
    if(r>m)  minn=min(que_min(l,r,m+1,t,rson),minn);
    return minn;
}
int que_max(int l,int r,int s,int t,int p)
{
    if(l<=s&&t<=r) return d[p].maxx;
    int m=(s+t)>>1;
    if(laz[p]) pushdown(s,t,p);
    int maxx=0;
    if(l<=m) maxx=max(que_max(l, r, s, m, lson), maxx);
    if(r>m) maxx=max(que_max(l, r, m+1, t, rson), maxx);
    return maxx;
}
int getsum(int l,int r,int s,int t,int p)
{
    if(l<=s&&t<=r) return d[p].sum;
    int m=(s+t)>>1;
    if(laz[p]) pushdown(s,t,p);
    int sum=0;
    if(l<=m) sum+=getsum(l,r,s,m,p<<1);
    if(r>m) sum+=getsum(l,r,m+1,t,p<<1|1);
    return sum;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;  cin>>n;
    string s;   cin>>s;
    int loc=1;
    for(auto i:s)
    {
        if(i=='L')  loc=max(1,loc-1);
        else if(i=='R') loc++;
        else {
            int k=a[loc];
            if(i=='(') a[loc]=1;
            else if(i==')') a[loc]=-1;
            else a[loc]=0;
            update(loc,n,-k+a[loc],1,n,1);
        }
        if(que_min(1,n,1,n,1)!=0||getsum(n,n,1,n,1)!=0) cout<<-1<<" ";
        else cout<<que_max(1,n,1,n,1)<<" ";
    }
    cout<<endl;
    return 0;
}