hiho一下21周 线段树的区间修改 离散化
离散化
描述
小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~
这天小Hi和小Ho所在的学校举办社团文化节,各大社团都在宣传栏上贴起了海报,但是贴来贴去,有些海报就会被其他社团的海报所遮挡住。看到这个场景,小Hi便产生了这样的一个疑问——最后到底能有几张海报还能被看见呢?
于是小Ho肩负起了解决这个问题的责任:因为宣传栏和海报的高度都是一样的,所以宣传栏可以被视作长度为L的一段区间,且有N张海报按照顺序依次贴在了宣传栏上,其中第i张海报贴住的范围可以用一段区间[a_i, b_i]表示,其中a_i, b_i均为属于[0, L]的整数,而一张海报能被看到当且仅当存在长度大于0的一部分没有被后来贴的海报所遮挡住。那么问题就来了:究竟有几张海报能被看到呢?
在线段树的通常用法中,线段树的节点是有2种不同的意义的,一种是离散型的,比如在Hiho一下 第二十周中,一个节点虽然描述的是一个区间[3, 9],但是实际上这样一个区间是{3, 4, 5, 6, 7, 8, 9}这样的意义。而另一种就是连续型的,比如就在这一周的问题中,一个节点如果描述的是一个区间[3, 9],它就确确实实描述的是在数轴上从3这个标记到9这个标记的这一段。
那么有的小朋友可能就要问了,这两种不同的意义有什么区别呢?
在小Hi看来,其实只有这样的几个区别:1.叶子节点:在离散型中,叶子节点是[i, i],而连续性中是[i, i + 1];2.分解区间:在离散型中,一段区间是分解成为[l, m], [m + 1, r],而在连续型中,是分解成为[l, m], [m, r];3.其他所有类似的判定问题。
那么亲爱的小朋友们,你们懂了么?
小Ho听完小Hi的描述,不屑道:“这不就是一个很简单的线段树问题么,每一张海报其实就是一次修改,在线段树上利用懒惰标记进行维护——“每个节点对应的区间上是否只有一张海报?如果有,是哪一张?”,然后在全部海报处理完成之后,扫描一遍整个线段树,看仍然‘存活’的海报有哪些,就可以知道答案了!”
“对,你说的很有道理!”小Hi点头表示赞同,又随即问道:“但是你这棵线段树有多大呢?”
“不就是O(N)大小的么……额,应该是O(L)大小的……因为叶子节点个数是L个,那么这个树的空间开出来,似乎内存要炸啊。”小Ho意识到了问题所在。
“那你准备如何处理?”小Hi问道。
“等等,我觉得很不科学啊……你想想,这个问题最关键的问题在于这N个区间之间的相互覆盖关系,而和这N个区间所处的‘舞台’也就是这个宣传栏没有什么关系,那么为什么解决这个问题的复杂度反倒会和舞台的宽度L有关呢?。”小Ho不解道。
小Hi点头道:“对,这就是关键问题,[1, 1000000]、[2, 1000001]这两个区间在这个问题中和[1, 3]、[2, 4]两个区间其实并没有什么不同,但是为了维护前一种情况所需要的线段树就是非常巨大的。”
小Ho沉思半刻,道:“那么我所需要解决的问题,就是将[1, 1000000]、[2, 1000001]这样的区间转化成和它等价的[1, 3]、[2, 4]这样的区间咯?唔……但是想要弄清楚N个区间之间的关系话,是很复杂的,更何况如果我在弄清楚这N个区间关系的过程中,想必这个题目的问题就已经得到解决了吧?”
小Hi笑道:“所以说你走了弯路,太着相于区间这个东西上面了。”
小Ho表示理解不能。
小Hi便继续道:“在这个问题的计算过程中,对于这些区间来说,其实并不会在乎具体数值是多少,而是在他们的左右端点之间互相进行比较而已。所以你就把这N个区间的左右端点——2N个整数提出来,处理一下呗?你要注意的是,这2N个数是什么其实并不重要,你可以把这2N个数替换成为任何另外2N个数,只要他们之间的相对大小关系不发生改变就可以。”
小Ho点了点头,想道:“这2N个数……在数轴上就是最多2N个点,如果我把其中数值最小的点命名为第1个点,简称‘1’,数值次小的点命名为第2个点,简称‘2’……依次类推,那么这些点最多就命名到第2N个点。也就是说他们的数值范围缩小到了O(N)级别,但是这2N个数的相对大小关系并没有发生改变。比如说[1, 1000000]、[2, 1000001]、[2, 10]这3个区间的左右端点组成的集合为{1, 2, 10, 1000000, 1000001},那么我就将这个集合对应到{1, 2, 3, 4, 5},那么原来的三个区间就变成了[1, 4]、[2, 5]、[2, 3]这3个区间,但是他们的相互覆盖关系却是一点变化都没有!”
小Ho又思考一番,觉得没有什么问题,于是道:“那么我需要额外做的事情就是在构建线段树之前对区间进行预处理:将区间的左右端点选出来,组成一个集合,然后将这个集合依次对应到正整数集合上,并且利用这个对应将原来的区间的左右端点更换为新的值。这样新构建的区间在这个问题中的答案和原来区间是一样的,但是新区间的范围就是O(N)这个级别的,我就可以用O(N)的时间复杂度和空间复杂度构建出线段树了!”
“是的呢!但是你要不要手动写一下尝试一下?离散化——将连续的区间转化成为离散的点在编写的过程中可还是有很多小问题的哦!”
输入
每个测试点(输入文件)有且仅有一组测试数据。
每组测试数据的第1行为两个整数N和L,分别表示总共贴上的海报数量和宣传栏的宽度。
每组测试数据的第2-N+1行,按照贴上去的先后顺序,每行描述一张海报,其中第i+1行为两个整数a_i, b_i,表示第i张海报所贴的区间为[a_i, b_i]。
对于100%的数据,满足N<=10^5,L<=10^9,0<=a_i<b_i<=L。
输出
对于每组测试数据,输出一个整数Ans,表示总共有多少张海报能被看到。
- 样例输入
-
5 10
4 10
0 2
1 6
5 9
3 4 - 样例输出
-
5
线段树离散化(连续性)模板#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#define inf 2e9
#define met(a,b) memset(a,b,sizeof a)
typedef long long ll;
using namespace std;
const int N = 2e6+;
const int M = 4e6+;
int n,sum[N],m,re=;
int Tree[N],lazy[N];
int num[N*],ans[N];
map<int,int>mp;
struct man{
int l,r;
}a[N*];
void pushdown(int pos){
if(Tree[pos]){
Tree[pos<<]=Tree[pos<<|]=Tree[pos];
Tree[pos]=;
}return;
} void update(int L,int R,int val,int l,int r,int pos) {
if(l>=L&&r<=R) {
Tree[pos]=val;
return;
}
if(l+==r)return;
int mid=(l+r)>>;
pushdown(pos);
if(L<=mid) update(L,R,val,l,mid,pos<<);
if(mid<R)update(L,R,val,mid,r,pos<<|);
}
void query(int L,int R,int l,int r,int pos) {
if(Tree[pos]&&!ans[Tree[pos]]){
ans[Tree[pos]]=;
re++;
return;
}
if(l+==r)return;
int mid=(l+r)>>;
pushdown(pos);
int ans=;
if(L<=mid) query(L,R,l,mid,pos<<);
if(R>mid) query(L,R,mid,r,pos<<|);
return;
}
int main() {
int ll,rr,cnt=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d%d",&a[i].l,&a[i].r);
num[cnt++]=a[i].l;
num[cnt++]=a[i].r;
}
sort(num,num+cnt);
int all=;
for(int i=;i<cnt;i++)if(!mp[num[i]])mp[num[i]]=++all;
for(int i=;i<=n;i++)update(mp[a[i].l],mp[a[i].r],i,,all,);
query(,all,,all,);
printf("%d\n",re);
return ;
}
hiho一下21周 线段树的区间修改 离散化的更多相关文章
- hiho一下20周 线段树的区间修改
线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了 ...
- poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 58269 ...
- hihoCode 1078 : 线段树的区间修改
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
- hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
- ZOJ 2301 Color the Ball 线段树(区间更新+离散化)
Color the Ball Time Limit: 2 Seconds Memory Limit: 65536 KB There are infinite balls in a line ...
- UVa 11992 Fast Matrix Operations (线段树,区间修改)
题意:给出一个row*col的全0矩阵,有三种操作 1 x1 y1 x2 y2 v:将x1 <= row <= x2, y1 <= col <= y2里面的点全部增加v: 2 ...
- HDU 1698 【线段树,区间修改 + 维护区间和】
题目链接 HDU 1698 Problem Description: In the game of DotA, Pudge’s meat hook is actually the most horri ...
- HZAU 1207 Candies(线段树区间查询 区间修改)
[题目链接]http://acm.hzau.edu.cn/problem.php?id=1207 [题意]给你一个字符串,然后两种操作:1,将区间L,R更新为A或者B,2,询问区间L,R最长的连续的B ...
- 培训补坑(day7:线段树的区间修改与运用)(day6是测试,测试题解以后补坑QAQ)
补坑咯~ 今天围绕的是一个神奇的数据结构:线段树.(感觉叫做区间树也挺科学的.) 线段树,顾名思义就是用来查找一段区间内的最大值,最小值,区间和等等元素. 那么这个线段树有什么优势呢? 比如我们要多次 ...
随机推荐
- web.xml中在Servlet中获取context-param和init-param内的参数
引自:http://blog.csdn.net/yakson/article/details/9203231 web.xml里面可以定义两种参数:1.application范围内的参数,存放在serv ...
- Dotspatial 创建面状图层
using DotSpatial.Controls;using DotSpatial.Data;using DotSpatial.Data.Forms;using DotSpatial.Plugins ...
- android小技巧(一)
1,调web浏览器 Uri myBlogUri = Uri.parse("http://xxxxx.com"); returnIt = new Intent(Intent.AC ...
- 学习中的错误——ubuntu 14.04 LTS 启动eclipse报错
在ubuntu中启动eclipse报错:(Eclipse:15978): GLib-GIO-CRITICAL **: g_dbus_connection_get_unique_name: assert ...
- ie11浏览器和chrome浏览器对于bgsound和background的一些区别
今天在编写一个非常简单的网页的时候,按照书上写的,使用了一个jpg图片作为背景图片,用background属性放在<body>标签内,同时使用<bgsound>标签插入背景音乐 ...
- Android深度探索--HAL与驱动开发----第二章读书笔记
1. 底层开发工具包括: JDk6或者以上版本:Eclipse3.4或以上版本:ADT(用于开发Android应用程序),CDT(用于开发AndroidNDK程序):Android SDK:Andro ...
- IE7下如何判断复选框是否被选中(利用jquery)
var checkM; $(".rate-mainL .checkM").click(function(){ var checkM=$("input[name='chec ...
- 库函数API和C语言汇编语言混合式编程
C语言代码内嵌汇编的方法: 在C语言文件中以如下格式加入汇编代码 __asm__( “汇编语句模板” :输出部分 :输入部分 :“破坏描述部分” ) asm可以由__asm__代替,为其别名. 可加上 ...
- Linux内核分析——分析system_call中断处理过程
万子惠 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 我选择的是get ...
- C#实现自动发送QQ消息
1.得打开需要发送的聊天窗口,最小化也可,聊天时不能是中文输入法2.然后AIO名就是窗口左上角的那个名称,括号和QQ号不要,那个名称可能是好友备注,群名称,讨论组名称等.3.发送消息要设置成按Ente ...