Codeforces Round #603 (Div. 2) E. Editor 线段树
E. Editor
The development of a text editor is a hard problem. You need to implement an extra module for brackets coloring in text.
Your editor consists of a line with infinite length and cursor, which points to the current character. Please note that it points to only one of the characters (and not between a pair of characters). Thus, it points to an index character. The user can move the cursor left or right one position. If the cursor is already at the first (leftmost) position, then it does not move left.
Initially, the cursor is in the first (leftmost) character.
Also, the user can write a letter or brackets (either (, or )) to the position that the cursor is currently pointing at. A new character always overwrites the old value at that position.
Your editor must check, whether the current line is the correct text. Text is correct if the brackets in them form the correct bracket sequence.
Formally, correct text (CT) must satisfy the following rules:
any line without brackets is CT (the line can contain whitespaces);
If the first character of the string — is (, the last — is ), and all the rest form a CT, then the whole line is a CT;
two consecutively written CT is also CT.
Examples of correct texts: hello(codeforces), round, ((i)(write))edi(tor)s, ( me). Examples of incorrect texts: hello)oops(, round), ((me).
The user uses special commands to work with your editor. Each command has its symbol, which must be written to execute this command.
The correspondence of commands and characters is as follows:
L — move the cursor one character to the left (remains in place if it already points to the first character);
R — move the cursor one character to the right;
any lowercase Latin letter or bracket (( or )) — write the entered character to the position where the cursor is now.
For a complete understanding, take a look at the first example and its illustrations in the note below.
You are given a string containing the characters that the user entered. For the brackets coloring module's work, after each command you need to:
check if the current text in the editor is a correct text;
if it is, print the least number of colors that required, to color all brackets.
If two pairs of brackets are nested (the first in the second or vice versa), then these pairs of brackets should be painted in different colors. If two pairs of brackets are not nested, then they can be painted in different or the same colors. For example, for the bracket sequence ()(())()() the least number of colors is 2, and for the bracket sequence (()(()())())(()) — is 3.
Write a program that prints the minimal number of colors after processing each command.
Input
The first line contains an integer n (1≤n≤106) — the number of commands.
The second line contains s — a sequence of commands. The string s consists of n characters. It is guaranteed that all characters in a string are valid commands.
Output
In a single line print n integers, where the i-th number is:
−1 if the line received after processing the first i commands is not valid text,
the minimal number of colors in the case of the correct text.
Examples
input
11
(RaRbR)L)L(
output
-1 -1 -1 -1 -1 -1 1 1 -1 -1 2
input
11
(R)R(R)Ra)c
output
-1 -1 1 1 -1 -1 1 1 1 -1 1
Note
In the first example, the text in the editor will take the following form:
(
^
(
^
(a
^
(a
^
(ab
^
(ab
^
(ab)
^
(ab)
^
(a))
^
(a))
^
(())
^
题意
题面很长,但看note一眼就能看懂。
就给你了一个编辑器,LR表示左右光标移动,小写字母和左右括号表示将光标位置修改为左右括号和字母。(如果你现在就是最左边,就不能往左边移动)
现在给你n次操作,让你判断是否为合法括号序列,如果合法输出最大的括号嵌套数量,否则输出-1
题解
视频题解 https://www.bilibili.com/video/av77514280/
假设(是1,)是-1
我们维护前缀和,合法的括号序列是所有和为0,且前缀和的最小值大于等于0。如果满足这个条件,俺么最大的括号嵌套数量就是前缀和的最大值。
这实际上可以用线段树来做
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+107;
#define inf 0x3f3f3f3f
struct node{
int l,r;//区间[l,r]
int add;//区间的延时标记
int sum;//区间和
int mx; //区间最大值
int mn; //区间最小值
}tree[maxn*4+5];//一定要开到4倍多的空间
void pushup(int index){
tree[index].sum = tree[index<<1].sum+tree[index<<1|1].sum;
tree[index].mx = max(tree[index<<1].mx,tree[index<<1|1].mx);
tree[index].mn = min(tree[index<<1].mn,tree[index<<1|1].mn);
}
void pushdown(int index){
if(tree[index].add){
tree[index<<1].sum += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;
tree[index<<1|1].sum +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;
tree[index<<1].mx += tree[index].add;
tree[index<<1|1].mx += tree[index].add;
tree[index<<1].mn += tree[index].add;
tree[index<<1|1].mn += tree[index].add;
tree[index<<1].add += tree[index].add;
tree[index<<1|1].add += tree[index].add;
tree[index].add = 0;
}
}
void build(int l,int r,int index){
tree[index].l = l;
tree[index].r = r;
tree[index].add = 0;//刚开始一定要清0
if(l == r){
scanf("%d",&tree[index].sum);
tree[index].mn = tree[index].mx = tree[index].sum;
return ;
}
int mid = (l+r)>>1;
build(l,mid,index<<1);
build(mid+1,r,index<<1|1);
pushup(index);
}
void updata(int l,int r,int index,int val){
if(l <= tree[index].l && r >= tree[index].r){
/*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
个数,所以区间和 以及 最值为:
*/
/*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
tree[index].mn = val;
tree[index].mx = val;
tree[index].add = val;//延时标记*/
//在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
//个数,所以区间和 以及 最值为:
tree[index].sum += (tree[index].r-tree[index].l+1)*val;
tree[index].mn += val;
tree[index].mx += val;
tree[index].add += val;//延时标记
return ;
}
pushdown(index);
int mid = (tree[index].l+tree[index].r)>>1;
if(l <= mid){
updata(l,r,index<<1,val);
}
if(r > mid){
updata(l,r,index<<1|1,val);
}
pushup(index);
}
int querySum(int l,int r,int index){
if(l <= tree[index].l && r >= tree[index].r){
return tree[index].sum;
//return tree[index].mn;
}
pushdown(index);
int mid = (tree[index].l+tree[index].r)>>1;
int ans = 0;
int Max = 0;
int Min = inf;
if(l <= mid){
ans += querySum(l,r,index<<1);
}
if(r > mid){
ans += querySum(l,r,index<<1|1);
}
return ans;
}
int queryMi(int l,int r,int index){
if(l <= tree[index].l && r >= tree[index].r){
return tree[index].mn;
}
pushdown(index);
int mid = (tree[index].l+tree[index].r)>>1;
int ans = 0;
int Max = 0;
int Min = inf;
if(l <= mid){
Min = min(queryMi(l,r,index<<1),Min);
}
if(r > mid){
Min = min(queryMi(l,r,index<<1|1),Min);
}
return Min;
}
int queryMx(int l,int r,int index){
if(l <= tree[index].l && r >= tree[index].r){
return tree[index].mx;
}
pushdown(index);
int mid = (tree[index].l+tree[index].r)>>1;
int ans = 0;
int Max = 0;
int Min = inf;
if(l <= mid){
Max = max(queryMx(l,r,index<<1),Max);
}
if(r > mid){
Max = max(queryMx(l,r,index<<1|1),Max);
}
//return ans;
return Max;
//return Min;
}
string s;
int ss[maxn];
int main(){
int n;
scanf("%d",&n);n=n+5;
build(1,n,1);
cin>>s;
int pos = 1;
vector<int>ans;
for(int i=0;i<s.size();i++){
if(s[i]=='('){
updata(pos,n,1,1-ss[pos]);
ss[pos]=1;
}else if(s[i]==')'){
updata(pos,n,1,-1-ss[pos]);
ss[pos]=-1;
}else if(s[i]=='L'){
if(pos>1)pos--;
//pos=max(pos,1);
}else if(s[i]=='R'){
pos++;
}else{
if(ss[pos]==1){
updata(pos,n,1,-1);
}else if(ss[pos]==-1){
updata(pos,n,1,1);
}
ss[pos]=0;
}
if(queryMi(1,n,1)==0&&querySum(n,n,1)==0){
ans.push_back(queryMx(1,n,1));
}else{
ans.push_back(-1);
}
}
for(int i=0;i<ans.size();i++){
cout<<ans[i]<<" ";
}
cout<<endl;
}
Codeforces Round #603 (Div. 2) E. Editor 线段树的更多相关文章
- Codeforces Round #603 (Div. 2) E. Editor(线段树)
链接: https://codeforces.com/contest/1263/problem/E 题意: The development of a text editor is a hard pro ...
- Codeforces Round #603 (Div. 2) E. Editor
E. Editor 题目链接: https://codeforces.com/contest/1263/problem/E 题目大意: 输入一个字符串S1含有‘(’ , ‘)’ , ‘R’ , ‘L’ ...
- Codeforces Codeforces Round #316 (Div. 2) C. Replacement 线段树
C. ReplacementTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/570/problem ...
- Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- Codeforces Round #765 Div.1 F. Souvenirs 线段树
题目链接:http://codeforces.com/contest/765/problem/F 题意概述: 给出一个序列,若干组询问,问给出下标区间中两数作差的最小绝对值. 分析: 这个题揭示着数据 ...
- 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- Codeforces Round #406 (Div. 2) D. Legacy 线段树建模+最短路
D. Legacy time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- Codeforces Round #278 (Div. 1) Strip (线段树 二分 RMQ DP)
Strip time limit per test 1 second memory limit per test 256 megabytes input standard input output s ...
- Codeforces Round #603 (Div. 2) E - Editor(线段树,括号序列)
随机推荐
- Kotlin版Aspect入门篇
介绍: AspectJ是一个面向切面编程的一个框架,它扩展了java语言,并定义了实现AOP的语法.在将.java文件编译为.class文件时默认使用javac编译工具,AspectJ会有一套符合ja ...
- SpringBoot项目里,让TKmybatis支持可以手写sql的Mapper.xml文件
SpringBoot项目通常配合TKMybatis或MyBatis-Plus来做数据的持久化. 对于单表的增删改查,TKMybatis优雅简洁,无需像传统mybatis那样在mapper.xml文件里 ...
- LeetCode刷题191124
博主渣渣一枚,刷刷leetcode给自己瞅瞅,大神们由更好方法还望不吝赐教.题目及解法来自于力扣(LeetCode),传送门. 算法: 给出一个无重叠的 ,按照区间起始端点排序的区间列表. 在列表中插 ...
- Linux(Centos7)下redis5集群搭建和使用
1.简要说明 2018年十月 Redis 发布了稳定版本的 5.0 版本,推出了各种新特性,其中一点是放弃 Ruby的集群方式,改为 使用 C语言编写的 redis-cli的方式,是集群的构建方式复杂 ...
- GNN 相关资料记录;GCN 与 graph embedding 相关调研
最近做了一些和gnn相关的工作,经常听到GCN 和 embedding 相关技术,感觉很是困惑,所以写下此博客,对相关知识进行索引和记录: 参考链接: https://www.toutiao.com/ ...
- MATLAB实例:绘制条形图
MATLAB实例:绘制条形图 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 用MATLAB绘制条形图,自定义条形图的颜色.图例位置.横坐标名称.显示条 ...
- day96_11_28 mongoDB与scrapy框架
一.mongodb mongodb是一个面向文档的数据库,而不是关系型数据库.不采用关系型是为了获得更好的扩展性. 它与mysql的区别在于它没有表连接,但是可以通过其他办法实现. 安装数据库. 上官 ...
- 【使用篇二】SpringBoot定时任务Scheduled(14)
在日常项目运行中,我们总会有需求在某一时间段周期性的执行某个动作.比如每天在某个时间段导出报表,或者每隔多久统计一次现在在线的用户量.在springboot中可以有很多方案去帮我们完成定时器的工作,有 ...
- 用dotnet core搭建web服务器(二)路由表与封装
https://gitee.com/lightsever/netcore_study/tree/master/server02_path 先上代码,首先我们把httpserver封装一下,以后用起来方 ...
- Java之通过接口获取数据并用JDBC存储到数据库中
最近做数据同步功能,从接口获取数据然后存到数据库中以便后续对数据进行相关操作,下面就贴一下相关代码. import com.alibaba.fastjson.JSON; import com.alib ...