题目链接


题目描述:

给定一个长度为\(~\)n\(~\)的字符序列\(~\)a,初始时序列中全部都是字符\(~\)L。

有\(~\)q\(~\)次修改,每次给定一个\(~\)x,做出如下变化:

\(~~\) 1. a\(_{x}\)\(~\)=\(~\)L \(\rightarrow\)a\(_{x}\)\(~\)=\(~\)R

\(~~\) 2. a\(_{x}\)\(~\)=\(~\)R \(\rightarrow\)a\(_{x}\)\(~\)=\(~\)L

对于一个只含字符 L,R 的字符串 s,若其中不存在连续的 L 和 R,则称 s 满足要求。

每次修改后,请输出当前序列 a 中最长的满足要求的连续子串的长度。


题目思路

\(~~\) 利用线段树来维护左右区间进而维护区间某一属性的最大值

\(~~\)维护区间的lmax,rmax,即以左端点开始的最大值和以右端点开始的最大值

\(~~\)这样一个区间的最大值就可以通过子区间的maxn,lmax,rmax来维护

具体措施如下:

\(~~\) 1. 当两个子区间相接的地方不能连在一起时:

\(~~~~~\) 那父区间的最大值只能由左右区间的最大值转移而来: maxn[u]\(~\)=\(~\) max(maxn[ls],maxn[rs]);

\(~~~~~\) 而父区间的lmax由左区间的lmax转移来,rmax由右区间的rmax转移来: lmax[u]\(~\)=\(~\)lmax[ls],rmax[u]\(~\)=\(~\)rmax[rs];

\(~~\) 2. 当两个子区间相接的地方能连在一起时:

\(~~~~~\) 父区间的最大值就要考虑存不存在左区间的\(~\)“rmax”\(~\)和右区间的\(~\)“lmax”\(~\)连在一起比左右区间的maxn大的情况了:

\(~~~~~~\)maxn[u]\(~\)=\(~\)max(rmax[ls]+lmax[rs],max(maxn[ls],maxn[rs]));

\(~~~~~\) 同时因为左右区间可以连接在一块,所以在转移rmax和lmax也要考虑到是否会存在连接在一起的可能:

\(~~~~~~\) if(rmax[rs]\(~\)=\(~\)整个右区间的长度):

\(~~~~~~~~~~\) rmax[u]\(~\)=\(~\)rmax[ls]\(~\)+\(~\)右区间长度;

\(~~~~~~\) if(lmax[ls]\(~\)=\(~\)整个左区间的长度):

\(~~~~~~~~~~\) lmax[u]\(~\)=\(~\)lmax[rs]\(~\)+\(~\)左区间长度;

综上所述我们就完成了线段树的维护了,根据我们的思路,这道题在维护的时候还需要同时记录每个区间的区间长度,左右边界的元素:

即len[\(~\)],pl[\(~\)],pr[\(~\)]


代码实现

# include<bits/stdc++.h>
using namespace std;
# define int long long
# define ls u<<1
# define rs u<<1|1
const int N = 2e5 + 10;
int a[N], p, n, m;
struct segtree {
int lmax[4 * N], rmax[4 * N], maxn[N << 2];
int pl[N << 2], pr[N << 2], len[N << 2];
void pushup(int u) {
lmax[u] = lmax[ls];
rmax[u] = rmax[rs];
pl[u] = pl[ls];
pr[u] = pr[rs];
maxn[u] = max(maxn[ls], maxn[rs]);
if (pr[ls] != pl[rs]) {
maxn[u] = max(maxn[u], rmax[ls] + lmax[rs]);
if (maxn[ls] == len[ls]) {
lmax[u] = len[ls] + lmax[rs];
}
if (maxn[rs] == len[rs]) {
rmax[u] = rmax[ls] + len[rs];
}
}
} void build(int u, int l, int r) {
len[u] = r - l + 1;
if (l == r) {
lmax[u] = rmax[u] = maxn[u] = 1;
pl[u] = pr[u] = 1;
len[u] = 1;
return;
}
int mid = l + r >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(u);
} void modify(int u, int l, int r, int L, int R, int c) {
if (L <= l && r <= R) {
pl[u] ^= 1;
pr[u] ^= 1;
return;
}
int mid = l + r >> 1;
if (L <= mid) modify(ls, l, mid, L, R, c);
if (mid + 1 <= R) modify(rs, mid + 1, r, L, R, c);
pushup(u);
} int query(int u, int l, int r, int L, int R) {
if (l >= L && r <= R) {
}
int mid = l + r >> 1;
if (R <= mid) return query(ls, l, mid, L, R);
else if (L > mid) return query(rs, mid + 1, r, L, R);
else return max(query(ls, l, mid, L, mid), query(rs, mid + 1, r, mid + 1, R)); }
} tr; signed main() {
cin >> n >> m;
tr.build(1, 1, n); while (m--) {
int x;
cin >> x;
tr.modify(1, 1, n, x, x, 1);
cout << max(tr.maxn[1], max(tr.lmax[1], tr.rmax[1])) << endl;
}
return 0;
}

同类题型:

  1. E. Non-Decreasing Dilemma

    \(~~~~\)代码:

P6492 STEP(线段树维护左右区间pushup)的更多相关文章

  1. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  2. 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数

    肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个 ...

  3. hdu_5726_GCD(线段树维护区间+预处理)

    题目链接:hdu_5726_GCD 题意: 给你n个数(n<=1e5)然后m个询问(m<=1e5),每个询问一个区间,问你这个区间的GCD是多少,并且输出从1到n有多少个区间的GCD和这个 ...

  4. FJUT3568 中二病也要敲代码(线段树维护区间连续最值)题解

    题意:有一个环,有1~N编号,m次操作,将a位置的值改为b,问你这个环当前最小连续和多少(不能全取也不能不取) 思路:用线段树维护一个区间最值连续和.我们设出两个变量Lmin,Rmin,Mmin表示区 ...

  5. [Codeforces]817F. MEX Queries 离散化+线段树维护

    [Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...

  6. hdu2795(线段树单点更新&区间最值)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题意:有一个 h * w 的板子,要在上面贴 n 条 1 * x 的广告,在贴第 i 条广告时要 ...

  7. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  8. 滑动窗口(poj,线段树维护区间最值)

    题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...

  9. Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)

    recursion有一个整数序列a[n].现在recursion有m次询问,每次她想知道Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 &l ...

随机推荐

  1. CSP-S 2020 T4 贪吃蛇 (双队列模拟)

    题面 题解 先看数据,T<=10,用平衡树或优先队列是可以拿70分的,大体思路和正解思路是一样的,每次直接修改,然后模拟. 我们模拟的时候,主要是在过程中算出最终被吃的有选择权的蛇的最后选择时刻 ...

  2. Linux KVM创建虚拟机

    原博文(https://www.cnblogs.com/supermao12/p/16382767.html) 开启虚拟化 KVM需要64位操作系统 [root@localhost 4.18.0-19 ...

  3. Linux云主机安全入侵排查步骤

    导语 经常有用户报障系统被植入恶意程序,如挖矿软件.ddos攻击病毒.syn映射攻击病毒等,可以按照以下流程为用户排查入侵病毒类型: 一.定位病毒进程 对于用户反馈云主机性能卡顿,CPU和内存占用较高 ...

  4. bean的作用域解析

    说明 意义 1.在Spring中,Bean的作用域可以通过scope属性来指定.    2.指定作用域的目的是 存储在此类单例bean的高速缓存中,并且对该命名bean的所有后续请求和引用都返回该高速 ...

  5. 在Windows 2012 R2上安装vcenter 5.5

    在Windows 2012 R2上安装vCenter 5.5做个实验,发现安装的时候卡在Install Directory service了. 重启后,再装也一样. 上网查了一下,说是要装好ADLDS ...

  6. 2020年12月-第01阶段-前端基础-HTML CSS 项目阶段(二)

    品优购项目(二) 1. 品优购首页布局 命名集合: 名称 说明 快捷导航栏 shortcut 头部 header 标志 logo 购物车 shopcar 搜索 search 热点词 hotwrods ...

  7. 【设计模式】Java设计模式 - 模板模式

    Java设计模式 - 模板模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...

  8. 使用nginx代理nexus,不是/根路径

    location /nexus/ { proxy_pass http://192.168.0.218:8081/; proxy_set_header Host $host:$server_port; ...

  9. k8s中pod的容器日志查看命令

    如果容器已经崩溃停止,您可以仍然使用 kubectl logs --previous 获取该容器的日志,只不过需要添加参数 --previous. 如果 Pod 中包含多个容器,而您想要看其中某一个容 ...

  10. ELK基于ElastAlert实现日志的微信报警 ---docker环境

    参考网址:https://github.com/anjia0532/elastalert-docker 1.拉取镜像: docker pull anjia0532/elastalert-docker: ...