题目描述

给定一个长度为 nn且初始值全为 00的序列。你需要支持以下两种操作:

  • Add L, R, hL,R,h:将序列 [L, R][L,R]内所有值小于 hh的元素都赋为 hh,此时不改变高度大于 hh的元素值
  • Remove L, R, hL,R,h:将序列 [L, R][L,R]内所有值大于 hh的元素都赋为 hh,此时不改变高度小于 hh的元素值

你需要输出进行 kk次上述操作之后的序列。

解析

显然每次操作会对一段区间的取值范围造成影响,那么不妨我们维护区间取值的上下界,就可以轻松A掉这题。

最简单的方法就是线段树(不过貌似有人高级数据结构T了233)

那么维护上下界实质上也就是维护区间最大最小值,所以我们每次打个lazytag以保留操作对区间的影响就行了。注意是打标记而不是维护信息,我们不用区间查询,维护了这堆信息也没用,还浪费时间。。。

最后输出我们把lazytag造成的所有影响很好的维护出来,再遍历一次整棵线段树输出叶子节点的lazytag就行了。

那如何维护lazytag呢?我们就要关注pushdown怎么弄。

设\(up(h),down(h)\)分别对应在线段树上进行Add,Remove两种操作,改变的高度为\(h\)。

对于\(up(h)\),设改变的区间上下界为\(u,d\):

  1. 若\(x<d\),不会对区间造成影响
  2. 若\(d<x<u\),此时\(d\)变为\(x\),\(u\)不变
  3. 若\(x>u\),此时\(d,u\)都变为\(x\)。

参考代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define N 2000010
using namespace std;
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct node{
int l,r;
int up,down;
}t[N<<2];
int n,k;
inline void pushdown(int p)
{
if(p==0) return;
if(t[p].up!=0){
t[p<<1].up=max(t[p].up,t[p<<1].up);
t[p<<1|1].up=max(t[p].up,t[p<<1|1].up);
if(t[p<<1].down<t[p].up) t[p<<1].down=t[p].up;
if(t[p<<1|1].down<t[p].up) t[p<<1|1].down=t[p].up;
t[p].up=0;
}
if(t[p].down!=INF){
t[p<<1].down=min(t[p].down,t[p<<1].down);
t[p<<1|1].down=min(t[p].down,t[p<<1|1].down);
if(t[p<<1].up>t[p].down) t[p<<1].up=t[p].down;
if(t[p<<1|1].up>t[p].down) t[p<<1|1].up=t[p].down;
t[p].down=INF;
}
}
inline void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;t[p].up=0,t[p].down=INF;
if(l==r) return;
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
inline void up(int p,int l,int r,int val)
{
if(l<=t[p].l&&t[p].r<=r){
t[p].up=max(t[p].up,val);
t[p].down=max(val,t[p].down);
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) up(p<<1,l,r,val);
if(r>mid) up(p<<1|1,l,r,val);
}
inline void down(int p,int l,int r,int val)
{
if(l<=t[p].l&&t[p].r<=r){
t[p].down=min(t[p].down,val);
t[p].up=min(t[p].up,val);
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) down(p<<1,l,r,val);
if(r>mid) down(p<<1|1,l,r,val);
}
inline void query(int p,int l,int r)
{
if(t[p].l==t[p].r){
printf("%d\n",t[p].up);
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) query(p<<1,l,r);
if(r>mid) query(p<<1|1,l,r);
}
int main()
{
n=read(),k=read();
build(1,1,n);
for(int i=1;i<=k;++i){
int cmd=read(),l=read(),r=read(),val=read();
++l,++r;
if(cmd==1) up(1,l,r,val);
else down(1,l,r,val);
}
query(1,1,n);
return 0;
}

P4560 [IOI2014]Wall 砖墙的更多相关文章

  1. LUOGU P4560 [IOI2014]Wall 砖墙 (线段树)

    传送门 解题思路 线段树打标记,刚开始想复杂了,维护了四个标记.后来才知道只需要维护一个最大值最小值即可,然后更新的时候分类讨论一下. 代码 #include<iostream> #inc ...

  2. 4364: [IOI2014]wall砖墙

    4364: [IOI2014]wall砖墙 链接 分析: 线段树,维护一个最大值,一个最小值. 代码: #include<bits/stdc++.h> ],*p1 = buf,*p2 = ...

  3. bzoj4364: [IOI2014]wall砖墙

    线段树打标记的好(luo)题 打打标记,记得下移 = =听说2000000是用来卡线段树的 = =怎么办呢,,, = =打个读入优化看看能不能卡过去吧 #include<cstdio> # ...

  4. BZOJ4364: [IOI2014]wall砖墙(线段树)

    题意 题目链接 Sol 一个显然的思路是维护最大最小值以及最大最小值的覆盖标记. https://paste.ubuntu.com/p/WXpBvzF6Y2/ 但实际上因为这题只需要输出最后的操作序列 ...

  5. 【[IOI2014]Wall 砖墙】

    好像随便一卡就最优解了 malao告诉我这道题挺不错的,于是就去写了写 这两个操作很有灵性啊,感觉这么有特点的数大概是需要分块维护的吧 但是并没有什么区间查询,只是在最后输出整个序列 于是我们就直接用 ...

  6. [IOI2014]Wall

    [IOI2014]Wall 题目大意: 给你一个长度为\(n(n\le2\times10^6)\)的数列,初始全为\(0\).\(m(m\le5\times10^5)\)次操作,每次让区间\([l_i ...

  7. 「IOI2014」Wall 砖墙

    题目描述 给定一个初始元素为 \(0\) 的数列,以及 \(K\) 次操作: 将区间 \([L, R]\) 中的元素对 \(h\) 取 \(max\) 将区间 \([L, R]\) 中的元素对 \(h ...

  8. BZOJ4364:[IOI2014]Wall

    浅谈区间最值操作与历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html 题目传送门:https://lydsy.com/JudgeOnline/pr ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. kafka高吞吐量的分布式发布订阅的消息队列系统

    一:kafka介绍kafka(官网地址:http://kafka.apache.org)是一种高吞吐量的分布式发布订阅的消息队列系统,具有高性能和高吞吐率. 1.1 术语介绍BrokerKafka集群 ...

  2. [转帖]在VirtualBox Linux 7u2 中安装Oracle RAC 12.2.0.1.0

    https://xiaoyu.blog.csdn.net/article/details/81980936

  3. HLP帮助文件源文件RTF文件的编写

    https://www.cnblogs.com/gaodu2003/archive/2008/12/17/1356861.html 举例说明如下: 每一节的标题在RTF文件中一般以特有的脚注($)指定 ...

  4. C语言指针的一些用法

    指针是C语言的灵魂,精华之所在.指针强大而危险,用得好是一大利器,用得不好是一大潜在危害.正是指针具有强大而又危险的特性,加上指针比较难,很多人用的不好,所以越是封装程度高的语言,越是没有指针的&qu ...

  5. PB 将菜单中的部分按钮设置为某些页面不可选中

    if tab_1.selectedtab = 9 or tab_1.selectedtab = 10 then uo_toolbarstrip.of_enable(uo_toolbarstrip.of ...

  6. postgresql学习之安装篇

    ---恢复内容开始--- 安装方法: 1.可以使用操作系统自带的安装源 2.可以使用官网下载的源码进行安装 3.可以使用编译好的包入.run格式的安装包安装(本文使用的是这种安装方法,下载地址http ...

  7. SPOJ Qtree系列

    Qtree1 将边权变为这条边连接的两个点中深度更深的点的点权,这样就可以变为带修改链上最大点权.直接树链剖分即可. 下面是一份C语言代码 #include<stdio.h> #inclu ...

  8. 【leetcode-78 dfs+回溯】 子集

    子集 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3],   [1],   ...

  9. ubuntu安装texlive2019

    1.下载texlive2019的iso文件,清华镜像地址:https://mirrors.tuna.tsinghua.edu.cn/CTAN/systems/texlive/Images/texliv ...

  10. 阿里巴巴 Java 开发手册(二): 常量定义

    1. [强制]不允许任何魔法值(即未经定义的常量)直接出现在代码中. 反例: String key = "Id#taobao_" + tradeId; cache.put(key, ...