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 }

 

posted @ 2019-12-03 20:36  yya雨  阅读(285)  评论(0编辑  收藏  举报