CF1263E Editor

题目大意

传送门
您要设计一个只有一行的打字机,这一行的长度是无限大,一开始可以认为每个字符都是空。您的打字机有一个光标只指向一个字符,一开始指向最左侧的字符。

使用者有三种操作:

L 将光标向左移一格(当光标已经在最左侧时,忽略这次操作)

R 将光标向右移一格

一个小写字符或者'(',')' 将当前字符替换为给定字符

您需要在每次操作后,判断这一行是否是合法括号序列(例如 (ahakioi) 就是合法的,(ige))(tscore 就是非法的),不是输出 -1,否则输出最多嵌套数(例如 ()(())()() 的最多嵌套数是 2,(()(()())())(()) 的最多嵌套数是 3)。

思路

把字符(记为1,把字符)记为-1
前缀和为0就是合法序列,最大的前缀和就是答案
用线段树维护即可

\(code\)

下面代码是错的,注意!一直没调出来,咕咕咕

#include<bits/stdc++.h>
using namespace std;
const int N=1000001;
int n,pos=1;
char s[N];
struct node {
    int maxn,minn,sum;
} tree[N*4];
void pushup(int rt) {
    tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
    tree[rt].maxn=max(tree[rt<<1|1].maxn,tree[rt<<1].maxn);
    tree[rt].minn=min(tree[rt<<1|1].minn,tree[rt<<1].minn);
}
void update(int rt,int l,int r,int place,int val) {
    if(l==r&&l==place) {
        tree[rt].maxn=val;
        tree[rt].minn=val;
        tree[rt].sum=val;
        return ;
    }
    int mid=(l+r)>>1;
    if(place<=mid) update(rt<<1,l,mid,place,val);
    else update(rt<<1|1,mid+1,r,place,val);
    pushup(rt);
}
int main() {
    cin>>n;
    scanf("%s",s+1);
    for(int i=1; i<=n; ++i) {
        if(s[i]=='R') pos++;
        else if(s[i]=='L') {
            if(pos>1) pos--;
        } else {
            if(s[i]=='(') update(1,1,n,pos,1);
            else if(s[i]==')') update(1,1,n,pos,-1);
            else update(1,1,n,pos,0);
        }
        if(tree[1].sum!=0||tree[1].minn<0) printf("-1 ");
        else printf("%d ",tree[1].maxn);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/pyyyyyy/p/12113308.html
今日推荐