就这道题的理论难度来说绿题是有点低了,但是这道题的实际难度来看,顶多黄题,所以建议加强数据或出数据升级版.

前置芝士

  1. 线段树:具体可以看我的另一篇文章.

具体做法

暴力的方法想必都会,所以来讲一下正解.看到标签是线段树,所以正解就是线段树了(毫无问题的逻辑).这颗线段树上的节点如果只记录区间中的最长的符合条件的区间长度想必是无法转移的,所以需要记录一下的量:

  1. 当前区间最左端开始的最长的符合条件的区间的长度
  2. 当前区间最右端开始的最长的符合条件的区间的长度
  3. 当前区间中最长的符合条件的区间的长度
  4. 当前区间的最左边的数
  5. 当前区间的最右边的数
  6. 当前区间的长度

然后就可以合并了.

下面是几个合并时需要注意的地方:

  1. 整棵树的最左端的值就是左子树的最左端的值(右边同理)
  2. 整棵树的中间的最长分符合区间为左右子树的最长区间中的大值,但如果左右区间在相连处的数字不同,那么左子树的右边可以和右子树的左边相连,所以还有和这两个数相加的数去一个max
  3. 整颗子树的如果从头到尾都符合时需要特别处理:当左右子树可以相连时整颗树的左右最大值不能直接从单一一棵子树中获得,而需要一棵完整的子树加上另一棵子树的一部分(也可能是全部)
如:
左子树:1 0 1
右子树 0 0 1
如果没有这个特判时那么整颗树的左边最长为3
但是如果相连后1 0 1 0 0 1,左边最长为4

代码

#include<bits/stdc++.h>
#define rap(i,first,last) for(int i=first;i<=last;++i)
#define Lson now*2
#define Rson now*2+1
#define Middle (left+right)/2
#define Left Lson,left,Middle
#define Right Rson,Middle+1,right
using namespace std;
const int maxN=1e5+7;
struct Tree//保存整棵树
{
int lmax,rmax,mmax,l,r,len;//如上所示的需要保留的值
}tree[maxN*4];
int N,M;
void PushUp(int now)
{
tree[now].lmax=tree[Lson].lmax;//先直接将子树的左右最长赋值到整颗数中
tree[now].rmax=tree[Rson].rmax;
tree[now].l=tree[Lson].l;//整颗树的左右值
tree[now].r=tree[Rson].r;
tree[now].mmax=max(tree[Lson].mmax,tree[Rson].mmax);//先从左右子树中中间的最长符合区间中取一个最大的
if(tree[Lson].r!=tree[Rson].l)//当左右可以相连时
{
tree[now].mmax=max(tree[now].mmax,tree[Lson].rmax+tree[Rson].lmax);//需要再取一个大值
if(tree[Lson].mmax==tree[Lson].len)//如上注意3
{
tree[now].lmax=tree[Rson].lmax+tree[Lson].len;
}
if(tree[Rson].mmax==tree[Rson].len)
{
tree[now].rmax=tree[Lson].rmax+tree[Rson].len;
}
}
}
void Build(int now=1,int left=1,int right=N)//建树,不多说
{
tree[now].len=right-left+1;
if(left==right)
{
tree[now].lmax=tree[now].rmax=1;
tree[now].mmax=1;
tree[now].l=tree[now].r=1;
return;
}
Build(Left);
Build(Right);
PushUp(now);
}
void UpData(int change,int now=1,int left=1,int right=N)//修改,因为只有单点修改所以也用不上懒标记,直接将覆盖需要修改位置的所有区间都修改就好了
{
if(left>change||right<change)return;
if(left==right)//到叶节点时
{
tree[now].l^=1;
tree[now].r^=1;
return;
}
UpData(change,Left);
UpData(change,Right);
PushUp(now);//合并
}
int Query()
{
return max(tree[1].mmax,max(tree[1].lmax,tree[1].rmax));//全局查找,直接在整颗树中找一个最长的附和条件时区间
}
int main()
{
scanf("%d%d",&N,&M);
Build();//建树
int change;
rap(i,1,M)
{
scanf("%d",&change);
UpData(change);//修改
printf("%d\n",Query());//查询
}
return 0;
}

「Luogu P2253 好一个一中腰鼓!」的更多相关文章

  1. 洛谷 P2253 好一个一中腰鼓! 题解

    P2253 好一个一中腰鼓! 题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:"忽一人 ...

  2. 洛谷P2253 好一个一中腰鼓!

    题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:“忽一人大呼:‘好一个安塞腰鼓!’满座寂然,无敢 ...

  3. 洛谷 P2253 好一个一中腰鼓!

    题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:“忽一人大呼:‘好一个安塞腰鼓!’满座寂然,无敢 ...

  4. P2253 好一个一中腰鼓!

    题意:给你一个序列,初始是0,每次一个操作,把一个数^=1 每次求出最长01串的长度 正解:线段树(虽然暴力能过) 对于每个区间,记录三个值 lmax,以l为首的01串长度 rmax,以r为尾的01串 ...

  5. luogu2253 好一个一中腰鼓!

    先说一个小trick,一开始我们把他赋值成是红.白相间的,查询就查询的是全红或全白即可. 然后就可以做啦 题解里面好像都是线段树 暴力的题解好像都被del了 貌似暴力交上去也过不了了 然后我想说 分块 ...

  6. 「Luogu P2060 [HNOI2006]马步距离」

    一道神奇的BFS 前置芝士 BFS(DFS):这次真的不是我懒,我也不知道DFS怎么写. STL中的set或者map. 具体做法 数据范围非常大,直接BFS肯定是一片黑色(指TLE,MLE),直接贪心 ...

  7. Android内存管理(4)*官方教程 含「高效内存的16条策略」 Managing Your App's Memory

    Managing Your App's Memory In this document How Android Manages Memory Sharing Memory Allocating and ...

  8. Loj #6069. 「2017 山东一轮集训 Day4」塔

    Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...

  9. Loj #6073.「2017 山东一轮集训 Day5」距离

    Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...

随机推荐

  1. 2019牛客暑期多校训练营(第七场)A String (字符串的最小表示)

    思路 这题思路如果是递归的话,应该是比较正确的.但是实际上只用切割两次就可以了. 先把原串从后向前切割一次,再把每一部分切割一次. 切两次的思路实际上是有漏洞的. 递归的思路,终点是,如果串长为1,或 ...

  2. idea 导入svn中java WEB项目

    1.打开idea 2.填写svn路径 3.指定本地路径 4.选择1.8 format 5.添加jdk 6.配置tomcat启动项目 File -- Project Structure

  3. 吴裕雄--天生自然TensorFlow2教程:链式法则

    import tensorflow as tf x = tf.constant(1.) w1 = tf.constant(2.) b1 = tf.constant(1.) w2 = tf.consta ...

  4. 扒网站工具 HTTrack Website Copier

    下载地址:http://www.pc6.com/softview/SoftView_30936.html 作者:匿名用户 链接:https://www.zhihu.com/question/34188 ...

  5. 堆(c++)

    5分钟速成堆 FBI⚠WARNING 本文要素过多 吐槽 堆是我迄今为止学过最简单的数据结构 我还没学会最小生成树.最短路时就学会了 堆实用高效,值得推荐 (如果你看完了这篇文章还不会,你可以直接Co ...

  6. php 基础知识 post 和get 两种传输方式的区别

    1.post更安全(不会作为url的一部分,不会被缓存.保存在服务器日志.以及浏览器浏览记录中) 2.post发送的数据量更大(get有url长度限制) 3.post能发送更多的数据类型(get只能发 ...

  7. SpringBoot 集成Log4j、集成AOP

    集成Log4j (1)在pom.xml中添加依赖 <!--去掉springboot默认的日志--> <dependency> <groupId>org.spring ...

  8. ElementUI 删除 el-table 当前选中行(不是selection列)

    一句话即可: this.表格绑定的data.splice(this.$refs.表格的ref.store.states.selection, 1)

  9. Ionic3记录之核心代码分析

    app.module.ts app的根模块,一些插件的引用需要在这里声明,告诉APP如何组装应用: app.componet.ts app的根组件,主要用来APP启动时和启动后的操作;

  10. web-pc项目中index页面分析

    先上HTML代码: <%@ page language="java" contentType="text/html; charset=UTF-8" pag ...