[UOJ 25] [IOI 2014] Wall 【线段树】
题目链接:UOJ - 25
题目分析
每个操作就是将被操作的数限制在一个区间,比如 Set_Max(5) 就是将被操作的数限定在了 [5, INF] 的区间里。
这些操作是可加的,但是必须按照顺序,不满足交换律。
对每个节点维护两个标记 Min_Tag[x], Max_Tag[x] ,表示这个节点的数被限制在了 [Max_Tag, Min_Tag] 的区间内。
最终的答案应该是 gmax(Max_Tag[x], gmin(MinTag[x], Val[x]))。其中 Val[x] 是 x 这个位置的初值。
对某一个节点进行 Set_Max(Num) 时,就是进行这样的操作: Max_Tag[x] = gmax(Max_Tag[x], Num); Min_Tag[x] = gmax(Min_Tag[x], Num);
对某一个节点进行 Set_Min(Num) 时,就是进行这样的操作: Max_Tag[x] = gmin(Max_Tag[x], Num); Min_Tag[x] = gmin(Min_Tag[x], Num);
PushDown(x) 的时候就是用 x 的 Max_tag, Min_Tag 对 x 的孩子进行操作。
这样维护两个标记,最后取答案的时候再用 gmax(Max_Tag[x], gmin(MinTag[x], Val[x])) 取答案就行了,不过这道题中初值都是0。
代码
#include "wall.h" const int MaxN = 2000000 + 5, MaxH = 100000 + 5; int Min_Tag[MaxN * 4], Max_Tag[MaxN * 4]; void Build(int x, int s, int t)
{
if (s == t)
{
Min_Tag[x] = MaxH;
Max_Tag[x] = -MaxH;
return;
}
Min_Tag[x] = MaxH;
Max_Tag[x] = -MaxH;
int m = (s + t) >> 1;
Build(x << 1, s, m);
Build(x << 1 | 1, m + 1, t);
} inline int gmin(int a, int b) {return a < b ? a : b;}
inline int gmax(int a, int b) {return a > b ? a : b;} inline void Paint_Max(int x, int Num)
{
Max_Tag[x] = gmax(Max_Tag[x], Num);
Min_Tag[x] = gmax(Min_Tag[x], Num);
} inline void Paint_Min(int x, int Num)
{
Max_Tag[x] = gmin(Max_Tag[x], Num);
Min_Tag[x] = gmin(Min_Tag[x], Num);
} inline void PushDown(int x)
{
Paint_Max(x << 1, Max_Tag[x]);
Paint_Max(x << 1 | 1, Max_Tag[x]);
Max_Tag[x] = -MaxH;
Paint_Min(x << 1, Min_Tag[x]);
Paint_Min(x << 1 | 1, Min_Tag[x]);
Min_Tag[x] = MaxH;
} void Set_Max(int x, int s, int t, int l, int r, int Num)
{
if (l <= s && r >= t)
{
Paint_Max(x, Num);
return;
}
PushDown(x);
int m = (s + t) >> 1;
if (l <= m) Set_Max(x << 1, s, m, l, r, Num);
if (r >= m + 1) Set_Max(x << 1 | 1, m + 1, t, l, r, Num);
} void Set_Min(int x, int s, int t, int l, int r, int Num)
{
if (l <= s && r >= t)
{
Paint_Min(x, Num);
return;
}
PushDown(x);
int m = (s + t) >> 1;
if (l <= m) Set_Min(x << 1, s, m, l, r, Num);
if (r >= m + 1) Set_Min(x << 1 | 1, m + 1, t, l, r, Num);
} void Get_Ans(int x, int s, int t, int *&P)
{
if (s == t)
{
*P++ = gmax(Max_Tag[x], gmin(0, Min_Tag[x]));
return;
}
PushDown(x);
int m = (s + t) >> 1;
Get_Ans(x << 1, s, m, P);
Get_Ans(x << 1 | 1, m + 1, t, P);
} void buildWall(int n, int k, int op[], int left[], int right[], int height[], int finalHeight[])
{
Build(1, 1, n);
for (int i = 0; i < k; ++i)
{
if (op[i] == 1) Set_Max(1, 1, n, left[i] + 1, right[i] + 1, height[i]);
else Set_Min(1, 1, n, left[i] + 1, right[i] + 1, height[i]);
}
int *P = finalHeight;
Get_Ans(1, 1, n, P);
return;
}
[UOJ 25] [IOI 2014] Wall 【线段树】的更多相关文章
- [UOJ UNR#1]奇怪的线段树
来自FallDream的博客,未经允许,请勿转载, 谢谢. 原题可以到UOJ看,传送门 如果存在一个点是白的,却有儿子是黑的,显然无解. 不然的话,只要所有黑色的“黑叶子”节点,即没有黑色的儿子的节点 ...
- [UOJ#334][NOIP2017]列队 平衡树/线段树/树状数组
题目链接 题意不说了,一辈子也忘不掉 解法1.平衡树 这题就是平衡树裸题,每一行开一棵维护前 \(m-1\) 个,最后一列单独维护,因为很多人没有用到,所以平衡树每个节点是一个区间(pair),分裂时 ...
- 2018.07.25 hdu5306Gorgeous Sequence(线段树)
传送门 线段树基本操作. 要求维护区间取min" role="presentation" style="position: relative;"> ...
- UOJ#467. 【ZJOI2019】线段树 线段树,概率期望
原文链接www.cnblogs.com/zhouzhendong/p/ZJOI2019Day1T2.html 前言 在LOJ交了一下我的代码,发现它比选手机快将近 4 倍. 题解 对于线段树上每一个节 ...
- UOJ#196. 【ZJOI2016】线段树 概率期望,动态规划
原文链接www.cnblogs.com/zhouzhendong/p/UOJ196.html 题解 先离散化,设离散化后的值域为 $[0,m]$ . 首先把问题转化一下,变成:对于每一个位置 $i$ ...
- uoj#228. 基础数据结构练习题(线段树区间开方)
题目链接:http://uoj.ac/problem/228 代码:(先开个坑在这个地方) #include<bits/stdc++.h> using namespace std; ; l ...
- uoj #228. 基础数据结构练习题 线段树
#228. 基础数据结构练习题 统计 描述 提交 自定义测试 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的 ...
- UOJ #228. 基础数据结构练习题 线段树 + 均摊分析 + 神题
题目链接 一个数被开方 #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",st ...
- UOJ46 【清华集训2014】玄学 【时间线段树】
题目链接:UOJ 这题的时间线段树非常的妙. 对时间建立线段树,修改的时候在后面加,每当填满一个节点之后就合并进它的父亲. 对于一个节点维护序列,发现这是一个分段函数,合并就是归并排序.于是就形成了差 ...
随机推荐
- SOA是什么
一.SOA是什么 SOA的全称是Service-Oriented Architecture,面向服务架构.是一种架构,不是一种具体的开发技术. 要真正理解什么是SOA需要从软件开发的技术发展史 ...
- 全文索引(三)lucene 分词 Analyzer
分词: 将reader通过阅读对象Analyzer字处理,得到TokenStream处理流程被称为分割. 该解释可能是太晦涩.查看示例,这个东西是什么感性的认识. 样品:一段文本"this ...
- C++之枚举
1. 声明枚举类型格式 enum Day{ Mon,Tue=5,Wed};//Mon=0;Tue=5;Wed=6 enumDay1{Mon1,Tue1,Wed1};//Mon1=0;Tue1=1;We ...
- LabView 快捷键
对象调整和移动Shift-click 选择多个对象,在现有选择的基础上添加对象(方向键) 以一个像素为单位移动所选对象Shift- 以几个像素为单位移动所选对象Shift-click (拖动对象) 在 ...
- 给EditText的drawableRight属性的图片设置点击事件 分类: 学习笔记 android 2015-07-06 13:20 134人阅读 评论(0) 收藏
这个方法是通用的,不仅仅适用于EditText,也适用于TextView.AutoCompleteTextView等控件. Google官方API并没有给出一个直接的方法用来设置右边图片的点击事件,所 ...
- Android(java)学习笔记178:BroadcastReceiver之 自定义广播
广播使用: 电台:对外发送信号.---------电台发送广播(可以自定义) 收音机:接收电台的信号.-----广播接收者 这里,我们就说明自定 ...
- JavaScript 开发规范要求详解
作为一名开发人员(We前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以及执行效率上的问题.本人在开发工作中就曾与不按规范来开发的同 ...
- Bash中的$符号
脚本名称:$0 PID:$$ 参数个数:$# 脚本返回值:$? 第x个参数:$x 第10个以上的参数加大括号:${10} 所有参数:$@ #!/bin/bash echo "The prog ...
- 多线程与Socket编程
一.死锁 定义: 指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁 ...
- SVN配置使用
文档规则 [本地工作区] :work copy ,本地工作副本: [主项目]:引用共用模块的新项目(工程) 最新版本(HEAD revision):版本库里文件或目录的最新版本 SA :SVN服务器的 ...