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;
}

原文地址:https://www.cnblogs.com/qscqesze/p/11961855.html

时间: 2024-10-02 19:58:26

Codeforces Round #603 (Div. 2) E. Editor 线段树的相关文章

Codeforces Round #401 (Div. 2) E 贪心,线段树

Codeforces Round #401 (Div. 2) A 循环节 B 暴力排一下 C 标记出来,但10^5,特耿直地码了个O(n^2)的上去,最气的是在最后3分钟的时候被叉== D 从后往前贪心暴糙一下就好.比赛时一眼瞄出来了不敢写,搞不懂这样竟然不会超时.. E. Hanoi Factory 题意:n个环体,内径a[i],外径b[i],高h[i].当 a[i+1]<b[i]<=b[i+1] 时,第 i 个环体可以堆在第 i+1个环体上.求可以堆出的最高高度. tags:佩服那些大佬,

Codeforces Round #603 (Div. 2) E. Editor(线段树)

链接: https://codeforces.com/contest/1263/problem/E 题意: 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 point

Codeforces Round #603 (Div. 2)

传送门 感觉脑子还是转得太慢了QAQ,一些问题老是想得很慢... A. Sweet Problem 签到. Code /* * Author: heyuhhh * Created Time: 2019/11/29 22:36:19 */ #include <iostream> #include <algorithm> #include <vector> #include <cmath> #include <set> #include <ma

Educational Codeforces Round 23 F. MEX Queries(线段树)

题目链接:Educational Codeforces Round 23 F. MEX Queries 题意: 一共有n个操作. 1.  将[l,r]区间的数标记为1. 2.  将[l,r]区间的数标记为0. 3.  将[l,r]区间取反. 对每个操作,输出标记为0的最小正整数. 题解: hash后,用线段树xjb标记一下就行了. 1 #include<bits/stdc++.h> 2 #define ls l,m,rt<<1 3 #define rs m+1,r,rt<&l

Educational Codeforces Round 37-F.SUM and REPLACE (线段树,线性筛,收敛函数)

F. SUM and REPLACE time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output Let D(x) be the number of positive divisors of a positive integer x. For example, D(2)?=?2 (2 is divisible by 1 and 2), D(6)?

HDU5638 / BestCoder Round #74 (div.1) 1003 Toposort 线段树+拓扑排序

Toposort 问题描述 给出nn个点mm条边的有向无环图. 要求删掉恰好kk条边使得字典序最小的拓扑序列尽可能小. 输入描述 输入包含多组数据. 第一行有一个整数TT, 表示测试数据组数. 对于每组数据: 第一行包含3个整数nn, mm和kk (1 \le n \le 100000, 0 \le k \le m \le 200000)(1≤n≤100000,0≤k≤m≤200000), 表示图中结点数目, 图中边的数目以及要删的边数. 接下来mm行, 每行包含两个整数u_iu?i?? and

Codeforces Round #603 (Div. 2)E

http://codeforces.com/contest/1263/problem/E 题意:求合法的括号序列 #include<bits/stdc++.h> using namespace std; typedef long long ll; #define lson root<<1,l,midd #define rson root<<1|1,midd+1,r #define pb push_back const int inf=0x3f3f3f3f; const

Codeforces Round #603 (Div. 2) A. Sweet Problem(数学)

链接: https://codeforces.com/contest/1263/problem/A 题意: You have three piles of candies: red, green and blue candies: the first pile contains only red candies and there are r candies in it, the second pile contains only green candies and there are g ca

Codeforces Round #603 (Div. 2) B. PIN Codes

链接: https://codeforces.com/contest/1263/problem/B 题意: A PIN code is a string that consists of exactly 4 digits. Examples of possible PIN codes: 7013, 0000 and 0990. Please note that the PIN code can begin with any digit, even with 0. Polycarp has n (