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

前置芝士

  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. 基于Tesseract实现图片文字识别

    一.简介  Tesseract是一个开源的文本识别[OCR]引擎,可通过Apache 2.0许可获得.它可以直接使用,或者使用API从图像中提取打印的文本,支持多种语言.该软件包包含一个ORC引擎[l ...

  2. Jmeter调度器小记

    jmeter的调度器中[持续时间(秒)]的优先级是高于[结束时间]和[启动时间]的 举例子: 前提:[循环次数]勾选[永远] 场景1:[持续时间(秒)]设置为120S,[启动时间]设置T+1min,[ ...

  3. gitlab回退到某次commit——本地+远程

    ## 查看所有commits记录$ git log ## gitlab回退到某次commit$ git reset --hard 3018a546427e1f865524b82b488d6a2721d ...

  4. 配置和验证AP功率

    1.针对自主AP(Autonomous AP) 使用'power local'配置命令配置AP或Bridge Radio功率级别.在2.4 GHz,802.11g Radio上,您可以设置正交频分复用 ...

  5. C语言-断言

    1 作用: 断言常做语言处理的高级形式,自动处理软件隐藏很深其且它手段不易发现的错误,快速进行异常定位.同时这也是软件单元测试必须的技术. 2 使用范围: 2.1放在函数入口对入口参数进行合法性检查( ...

  6. video标签 在微信浏览器打开,不弹出大的独立窗口 而是直接播放。

    1.在 video 标签中添加   属性    x5-playsinline  playsinline  webkit-playsinline="true" 2.ckplayer的 ...

  7. 输入流输出流IO的理解

    之前对IO理解总是有点模糊, 输入输出,其实针对 数据处理主体 A ,这个主体我们通常是指服务器程序本身,   交互目的源B ,一般是本地磁盘,由本地磁盘IO传输, 或者 远程客户端,由网络IO传输. ...

  8. Centos610无桌面安装Docker-安装

    1.必备环境 设定docker源yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.rep ...

  9. mssql-osql

    mssql导入单行字段值非常长,或者sql文件非常大,比如上百M或者更大,常规方法是导不进去的,所以推荐下面方式进行导入. osql -S . -U sa -P 123456 -d TS_TEST - ...

  10. SpringSecurity配置,简单梳理

    生活加油:摘一句子: “我希望自己能写这样的诗.我希望自己也是一颗星星.如果我会发光,就不必害怕黑暗.如果我自己是那么美好,那么一切恐惧就可以烟消云散.于是我开始存下了一点希望—如果我能做到,那么我就 ...