题目大意
传送门
您要设计一个只有一行的打字机,这一行的长度是无限大,一开始可以认为每个字符都是空。您的打字机有一个光标只指向一个字符,一开始指向最左侧的字符。
使用者有三种操作:
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;
}