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)
补坑咯~ 今天围绕的是一个神奇的数据结构:线段树.(感觉叫做区间树也挺科学的.) 线段树,顾名思义就是用来查找一段区间内的最大值,最小值,区间和等等元素. 那么这个线段树有什么优势呢? 比如我们要多次 ...
随机推荐
- SDWebImage下载图片有时候无法成功显示出来
之前用下面的方法现在图片,有时候会出现图片没有下载成功显示: - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)p ...
- MySQL workbench 中文乱码 显示口口
Edit-->perference...-->Apperance 如下图 即可 转载自:http://blog.csdn.net/shxluwei/article/details/802 ...
- JDBC driver connection string大全
Database / data source URL format / driver name Value Default port MySQL URL format: jdbc:mysql: ...
- WIN7-64位安装PLSQL-Developer步骤
可参与网址http://tech.ddvip.com/2012-07/1343104017178927.html 以下操作是从网上搜索在64位WIN7测试通过,64位无法使用PL/SQL Develo ...
- 关于由CSS2.1所提出的的BFC的理解与样例
今天在这里谈谈css中BFC.“BFC”是Block Formatting Context的缩写,这个概念是由CSS2.1提出来的,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用.满 ...
- TestNG插件的安装问题
一.可以采用离线安装的方式 离线安装若不成功,可以删除之前的eclipse,然后在新下载eclipse中添加离线安装包 1.离线安装方法: 发现很多同学和我一样无法在线安装testNg,现在分享一个离 ...
- MySQL5.6下使用xtrabackup部分备份恢复到MySQL5.7
现有需求:需要备份MySQL5.6环境下的部分表到MySQL5.7环境下并进行恢复 通过xtrabackup 实现部分备份有三种方式: 参考链接:http://blog.csdn.net/zhu197 ...
- swift 命名,字符串
命名: let numberOfDogs = 6 +2; 字符串连接: let finishedMessage = username + "xx" + password; 字符串 ...
- PHP面试题之驼峰字符串转换成下划线样式例子
自己在看到这个问题的时候,想到的是用ASCII码来处理,没往万能的正则上去想.好吧,下面来看看答案: 答案1: 代码如下 复制代码 $str = 'OpenAPI'; $length = mb_str ...
- STM32 Cube固件库编程之新建工程
Cube固件库是ST现在主推的固件库,并且在它的官网已经找不到原来的标准库可供下载.Cube固件库的构架图如下 这种新式构架可以有效的加快软件工程师的工程进度. 新建一个工程项目主要包括以下的步骤: ...