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

前置芝士

  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. 前端必学---JavaScript数据结构与算法---简介

    前端必学---JavaScript数据结构与算法---简介 1. 数据结构: 数据结构是相互之间存在一种或者多种特定关系的数据元素的集合.---<大话数据结构> 1.1 数据结构的分类 1 ...

  2. ARG 构建参数----Dockerfle文件的重用

    ARG 构建参数----Dockerfle文件的重用 格式:ARG <参数名>[=<默认值>] 构建参数和 ENV 的效果一样,都是设置环境变量. 所不同的是,ARG 所设置的 ...

  3. 夯实Java基础(二十五)——JDBC使用详解

    1.JDBC介绍 JDBC的全称是Java Data Base Connectivity(Java数据库连接).是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问(例如MyS ...

  4. class A<T>where T:new()是什么意思

    这是C#泛型类声明的语法class A<T> 表示 A类接受某一种类型,泛型类型为T,需要运行时传入where表明了对类型变量T的约束关系.where T:new()指明了创建T的实例时应 ...

  5. 「JSOI2011」棒棒糖

    「JSOI2011」棒棒糖 传送门 双倍经验 考虑主席树做法. 对于当前的主席树节点,如果 \(\le mid\) 的个数足够就往左边走,否则就尝试往右边走,都不行就返回 \(0\). 参考代码: # ...

  6. slice 、 substr 、replace

    slice( 参数1  [,参数2] )        (注意不要让[参数1]下标越过[参数2]下标,否则会得到空字符串,且[参数2]是不包含在截取范围内的) 参数1:截取字符的[起始下标]. 值为正 ...

  7. Python - 代码片段,Snippets,Gist

    说明 代码片段来自网上搬运的或者自己写的 华氏温度转摄氏温度 f = float(input('请输入华氏温度: ')) c = (f - 32) / 1.8 print('%.1f华氏度 = %.1 ...

  8. 去重sort|uniq -d

    #!/bin/bash ############################################################### #Author :Bing # #Create ...

  9. git github 对代码的管理

    参考:https://www.cnblogs.com/feynman61/p/9005252.html 一.Git 对远程仓库版本回退 场景: 同事 a.b 同时修改了代码,提交到仓库 同时 c 不熟 ...

  10. c++模板(翁恺c++公开课[34-35]学习笔记)

    为什么要有模板(templates):当我们需要一个列表(list),列表中元素可能都为X类型也可能都为Y类型,怎么来实现呢? 定义基类?可以实现,很多情况下可能不够简明的表达设计思想 克隆代码(写一 ...