Codeforces Round #603 (Div. 2) E. Editor
E. Editor
题目链接:
https://codeforces.com/contest/1263/problem/E
题目大意:
输入一个字符串S1含有‘(’ , ‘)’ , ‘R’ , ‘L’ 以及其他字符。根据这个字符串,得到相应的字符串S2。起始idx=1即S2的初始坐标,然后从左到右读取S1,当遇到'L',idx减小1(当无法左移的情况下idx不减小),当遇到'R',idx增加1,当读取到其他字符时,将idx这个位置上的字符更新为读取到的新的字符。然后输出每一步得到的字符串S2最大的括号级数(例:(()())为2,((()))为3),如果不是一个左右括号完全匹配的字符串输出-1。
解题思路:
另(为1,)为-1,其他字符为0,构造一个线段树,维护区间和与前缀最小值、前缀最大值。可以知道,当前缀最小值小于0时代表不是一个括号完全匹配的字符串,当区间和不为0也表示这不是一个括号完全匹配的字符串。
代码:
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N = 4e6;
4 string s;
5 int ans[N];
6 int mi[N],ma[N];
7
8 void update(int node,int start,int end,int p,int v){
9 if(start==end){
10 ans[node]=v;
11 ma[node]=v;
12 mi[node]=v;
13 return ;
14 }
15 int mid=(start+end)>>1;
16 int left_node=2*node+1;
17 int right_node=2*node+2;
18 if(p<=mid){
19 update(left_node,start,mid,p,v);
20 }
21 else{
22 update(right_node,mid+1,end,p,v);
23 }
24 ans[node]=ans[left_node]+ans[right_node];
25 ma[node]=max(ma[left_node],ans[left_node]+ma[right_node]);// 一个区间前缀最大值是左边区间中的最大值,与右边区间最大值加上左边区间和中的最大值
26 mi[node]=min(mi[left_node],ans[left_node]+mi[right_node]);// 一个区间前缀最小值是左边区间中的最小值,与右边区间最小值加上左边区间和中的最小值
27 }
28
29 int main(){
30 int n,idx=1;
31 cin>>n>>s;
32 for(int i=0;i<n;i++){
33 if(s[i]=='L'){
34 if(idx>1) idx--;
35 }
36 else if(s[i]=='R'){
37 idx++;
38 }
39 else if(s[i]=='('){
40 update(1,1,n,idx,1);//更新此位置改为1
41 }
42 else if(s[i]==')'){
43 update(1,1,n,idx,-1);//更新此位置改为-1
44 }
45 else{
46 update(1,1,n,idx,0);//更新此位置改为0
47 }
48 if(mi[1]>=0&&ans[1]==0){//判断输出
49 cout<<ma[1]<<" ";
50 }
51 else{
52 printf("-1 ");
53 }
54 }
55 cout<<endl;
56
57
58 return 0;
59 }