题意:有一个无限长度的文本编辑器,刚开始没有内容,光标在第一格,接下来有n个操作,操作可能有3种:

1.光标左移一格,如果已经在第一格则不动

2.光标右移一格

3.将当前光标所在格的字符改成输入的字符

每次操作后问当前所有内容对于括号序列是否合法,若非法输出-1,否则输出括号的最大层数

n<=1e6

思路:最大层数即将左括号看做-1,右括号看做1之后的最大前缀和

做法一:线段树单点修改

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,ll>P;
#define N 2000000+10
#define M 200000+10
#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1
#define fors(i) for(auto i:e[x]) if(i!=p) const int MOD=,inv2=(MOD+)/;
//int p=1e4+7;
//double eps=1e-6;
int dx[]={-,,,};
int dy[]={,,-,}; struct node
{
int s,mx,mn;
}t[N<<]; char s[N]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} ll readll()
{
ll v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void build(int l,int r,int p)
{
t[p].s=t[p].mx=t[p].mn=;
if(l==r) return;
int mid=(l+r)>>;
build(l,mid,ls);
build(mid+,r,rs);
} void pushup(int p)
{
t[p].s=t[ls].s+t[rs].s;
t[p].mx=max(t[ls].mx,t[ls].s+t[rs].mx);
t[p].mn=min(t[ls].mn,t[ls].s+t[rs].mn);
} void update(int l,int r,int x,int d,int p)
{
if(l==r)
{
t[p].s=d;
t[p].mx=d;
t[p].mn=d;
return;
}
int mid=(l+r)>>;
if(x<=mid) update(l,mid,x,d,ls);
else update(mid+,r,x,d,rs);
pushup(p);
} int main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
int n=read();
build(,1e6+,);
int now=;
rep(i,,n)
{
char c=getchar();
if(c=='L')
{
if(now>) now--;
if(t[].s!=||t[].mn<) printf("-1 ");
else printf("%d ",t[].mx);
//printf("now=%d t[1].s=%d t[1].mx=%d\n",now,t[1].s,t[1].mx);
continue;
}
if(c=='R')
{
now++;
if(t[].s!=||t[].mn<) printf("-1 ");
else printf("%d ",t[].mx);
//printf("now=%d t[1].s=%d t[1].mx=%d\n",now,t[1].s,t[1].mx);
continue;
}
int d=;
s[now]=c;
if(c=='(') d=;
if(c==')') d=-;
update(,1e6+,now,d,);
if(t[].s!=||t[].mn<) printf("-1 ");
else printf("%d ",t[].mx);
//printf("now=%d t[1].s=%d t[1].mx=%d\n",now,t[1].s,t[1].mx);
}
return ;
}

思路二:用栈维护光标左边的内容,右边的内容和当前左部分前缀和对于真正值的偏移量,维护的信息和线段树差不多

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,ll>P;
#define N 2000000+10
#define M 200000+10
#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1
#define fors(i) for(auto i:e[x]) if(i!=p) const int MOD=,inv2=(MOD+)/;
//int p=1e4+7;
//double eps=1e-6;
int dx[]={-,,,};
int dy[]={,,-,}; int a[N],s[N]; struct Set
{
int mn,mx;
int cnt[];
Set():mn(),mx(),cnt{}{cnt[]=;}
void Insert(int x)
{
cnt[x+]++;
mn=min(mn,x);
mx=max(mx,x);
}
void Erase(int x)
{
cnt[x+]--;
while(cnt[mn+]==) mn++;
while(cnt[mx+]==) mx--;
}
}; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} ll readll()
{
ll v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} int main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
int n=read();
//printf("n=%d\n",n);
int offset=,p=,tot=;
Set l,r;
rep(i,,n)
{
char c=getchar();
if(c=='L')
{
if(p>)
{
l.Erase(s[p]);
p--;
r.Insert(-offset);
offset+=a[p];
}
}
else if(c=='R')
{
offset-=a[p];
r.Erase(-offset);
p++;
s[p]=s[p-]+a[p-];
l.Insert(s[p]);
}
else
{
int v=;
if(c=='(') v=;
if(c==')') v=-;
offset+=v-a[p];
tot+=v-a[p];
a[p]=v;
}
if(tot!=||min(l.mn,offset+s[p]+r.mn)<) printf("-1\n");
else printf("%d\n",max(l.mx,offset+s[p]+r.mx));
}
return ;
}

【CF1263E】Editor(线段树,栈)的更多相关文章

  1. Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor 线段树模拟

    E. Correct Bracket Sequence Editor   Recently Polycarp started to develop a text editor that works o ...

  2. Codeforces 670E - Correct Bracket Sequence Editor - [线段树]

    题目链接:https://codeforces.com/contest/670/problem/E 题意: 给出一个已经匹配的括号串,给出起始的光标位置(光标总是指向某个括号). 有如下操作: 1.往 ...

  3. 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 ...

  4. codeforces div2 603 E. Editor(线段树)

    题目链接:https://codeforces.com/contest/1263/problem/E 题意:一个编译器,每次输入一些字符,R表示光标右移,L表示光标左移,然后有一些左括号(  和 右括 ...

  5. hdu4699 Editor 2013 多校训练第十场 D题 数列维护 splay | 线段树 | 栈!!!!!

    题意:维护一个文本编辑,并且查询最大前缀和. 写了splay,wa了13次 过了之后觉着特傻逼.发现题解两个栈就可以了,光标前后维护两个栈,维护前面的栈的前缀和 和 最大前缀和. 哎,傻逼,太弱了,还 ...

  6. The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...

  7. 2019南昌网络赛-I(单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...

  8. 网络赛 I题 Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...

  9. 南昌邀请赛I.Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a in ...

随机推荐

  1. c++学习之对象和类——构造函数和析构函数

    再认真理一遍~ 0.类 这里先来定义一个类,便于后面的理解.参考C++ Primer Plus class Stock { private: std::string company; long sha ...

  2. HTML5地图分布动画

    在线演示 本地下载

  3. EBS自动行号,行金额自动汇总到头,金额根据币种编号总结

    一.自动行号实现 1.方法一: 只需要将“序号”定义成公式,并将公式设置为:get_block_property('block_name',current_record)就可以实现了,或者把这行语句放 ...

  4. gitlab操作笔记

    基本命令 准备 1. 安装所需命令 sudo yum install curl openssh-server openssh-clients postfix cronie -y2. 安装SSH sud ...

  5. php和java语法区别

    Java和PHP的基本语法基本相同,其实大部分的语言的基本语法也都相同,但是他们还是有一些细微的区别: 1.PHP是一种脚本语言,代码在服务器上执行,而结果以纯文本返回浏览器. 2.PHP能够运行在各 ...

  6. Design Support库中的控件

    1.NavigationView滑动菜单 2.FloatIngActionButton悬浮按钮 3.Snackbar二次交互提示的按钮 4.Coordinatorlayout,监听子控件的各种事件(加 ...

  7. PC端微信扫码支付和支付宝跳转支付

    import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; impo ...

  8. vscod插件

    Babel JavaScript Code Runner Debugger for Chrome ESLint HTML CSS Support HTML Snippets background  J ...

  9. vue组件之属性Props

    组件的属性和事件 父子组件之间的通信 父子组件之间的通信就是 props down,events up,父组件通过 属性props向下传递数据给子组件,子组件通过 事件events 给父组件发送消息. ...

  10. 深入简出mysql--第一部分

    第二章: 1.sql分类 DDL(Data Definition Languages)语句:数据定义语言,这些语句定义了不同的数据段.数据库.表.列.索引等数据库对象的定义. 常用的语句关键字主要包括 ...