POJ - 2528 区间离散化,线段树区间修改,区间询问
这个题非常有意思的地方是,我们发现区间[1,4]和[5,8]是紧挨着的,因为这个的数代表的是一段区间,原本我们对于普通的离散,
a[1]=1,a[2]=5,a[3]=6,a[4]=8;数组下标就是重新离散的位置,但是a[2]和a[3]明显不重叠,为此我们需要重新考虑离散的内容,其实不妨这样,如果区间的间隔大于1,那么我们插入一个数a[i]+1,这样就强行把a[i]和a[i+1]分开,因为
如三张海报为:1~10 1~4 6~10
离散化时 X[ 1 ] = 1, X[ 2 ] = 4, X[ 3 ] = 6, X[ 4 ] = 10
第一张海报时:墙的1~4被染为1;
第二张海报时:墙的1~2被染为2,3~4仍为1;
第三张海报时:墙的3~4被染为3,1~2仍为2。
最终,第一张海报就显示被完全覆盖了,于是输出2,但实际上明显不是这样,正确输出为3。
新的离散方法为:在相差大于1的数间加一个数,例如在上面1 4 6 10中间加5(算法中实际上1,4之间,6,10之间都新增了数的)
为什么会这样呢?我们这样考虑,如果a[1]=3,a[2]=4那么他们两个是相邻的,这样其实离散后他们还是相邻的(因为1,2在题目的意义是相邻的),但是如果是a[1]=3,a[2]=5哈希后其实是(1,2) 它是相邻的(实际上3,5不相邻),于是我们想到这样,既然我们中间有一段(没有数那一段)是我们所忽略的,我们可以新加一个数4,如
a[1]=3 a[2]=4 a[3]=5; 这样哈希后是1,2,3,我们认为3->1而5->3,(1,3)其实是不相邻的。这道题也就没什么问题了,最后区间查询+区间修改。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = ;
int sum[maxn<<];
int vis[maxn<<];
int li[maxn*];
int ri[maxn*];
int lsh[maxn<<];
void pushdown(int root){//把节点信息传给儿子节点
sum[root<<]=sum[root];//相应这个节点如果最后被修改成这个结果,那么他的儿子节点也应该修改
sum[root<<|]=sum[root];
sum[root]=-;//清空laze标记
}
int ans;
void update(int root,int L,int R,int C,int l,int r){
if (L<=l && r<=R)//如果被修改区间完全盖过当前区间
{
sum[root]=C;//更新
return;
}
if (sum[root]!=-)
pushdown(root);//如果不满足上述条件,我们需要把节点的信息更新,
int m=(l+r)>>;
if (m>=R)update(root<<,L,R,C,l,m);//信息完全在左子树
else if(L>m)update(root<<|,L,R,C,m+,r);//完全在右子树
else update(root<<,L,m,C,l,m),update(root<<|,m+,R,C,m+,r);
}
void query(int root,int l,int r){
// cout<<root<<endl;
if (sum[root]!=- && !vis[sum[root]])//如果当前节点的信息已经能包含所有的节点信息,并且这个节点的信息是第一次访问到
{
ans++;
vis[sum[root]]=;
return;
}
if (l==r)
{
return;
}
if (sum[root]!=-)
pushdown(root);//更新标记
int m=(l+r)/;
query(root<<,l,m);
query(root<<|,m+,r);
}
int main(){
int t;
int n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(sum,-,sizeof(sum));
memset(vis,,sizeof(vis));
int tot=;
for (int i=;i<n;i++)
{
scanf("%d%d",&li[i],&ri[i]);
lsh[tot++]=li[i];
lsh[tot++]=ri[i];
}
sort(lsh,lsh+tot);
int mm=unique(lsh,lsh+tot)-lsh;
int tt=mm;
for (int i=;i<tt;i++)
{
if (lsh[i]-lsh[i-]>)
lsh[mm++]=lsh[i-]+;
}
sort(lsh,lsh+mm);//排序 按照数组下标进行离散
for (int i=;i<n;i++){
int x=lower_bound(lsh,lsh+mm,li[i])-lsh;//查找左边的离散后的号码
int y=lower_bound(lsh,lsh+mm,ri[i])-lsh;//查找右边的离散后的号码
update(,x,y,i,,mm-);//更新
}
ans=;
query(,,mm-);
printf("%d\n",ans);
}
return ;
}
POJ - 2528 区间离散化,线段树区间修改,区间询问的更多相关文章
- xdoj-1324 (区间离散化-线段树求区间最值)
思想 : 1 优化:题意是覆盖点,将区间看成 (l,r)转化为( l-1,r) 覆盖区间 2 核心:dp[i] 覆盖从1到i区间的最小花费 dp[a[i].r]=min (dp[k])+a[i]s; ...
- POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】
任意门:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total S ...
- HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 4417.Super Mario-可持久化线段树(无修改区间小于等于H的数的个数)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- BZOJ4653(区间离散化+线段树+决策单调尺取)
写得很好的题解 一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除.然后事实也是这样做的…… 具体起来: 1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按 ...
- [Noi2016]区间[离散化+线段树维护+决策单调性]
4653: [Noi2016]区间 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 621 Solved: 329[Submit][Status][D ...
- poj 2528 poster经典线段树+lazy+离散化
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; ; #def ...
- Lightoj 1348 Aladdin and the Return Journey (树链剖分)(线段树单点修改区间求和)
Finally the Great Magical Lamp was in Aladdin's hand. Now he wanted to return home. But he didn't wa ...
- I Hate It HDU - 1754 线段树 单点修改+区间最值
#include<iostream> #include<cstring> using namespace std; ; int m,n,p; struct node{ int ...
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
随机推荐
- 关于cisco日志的配置
实例: en conf t clock timezone GMT+8 #设置北京时间 exit clock set HH:MM:SS DAY MONTH YEAR #设置当前时间 service ...
- oracle外部表
关于外部表的描述 正确描述 the create table as select statement can be used to upload data into a normal table in ...
- 排序算法之折半插入排序的思想以及Java实现
1 基本思想 折半插入排序(binary insertion sort)的基本原理与直接插入排序相同,不同之处在于,确定当前记录在前面有序子数组中的位置时,直接插入排序是采用顺序查找的方法,而折半插入 ...
- GitHub-版本管理
参考博文:廖雪峰Git教程 1. 管理修改 现在,假定你已经完全掌握了暂存区的概念.下面,我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件. 你会问, ...
- 《Java大学教程》—第23章 Java网络编程
本章主要关注的是Java的几个应用网络编程的场景,对于网络编程没有太多深入介绍,而Java本来也没有多少针对网络编程的特性.虽然Java有个Applet的概念,但是真用这个的开发的场景其实不多. 23 ...
- hdfs fsck命令查看HDFS文件对应的文件块信息(Block)和位置信息(Locations)
关键字:hdfs fsck.block.locations 在HDFS中,提供了fsck命令,用于检查HDFS上文件和目录的健康状态.获取文件的block信息和位置信息等. fsck命令必须由HDFS ...
- [容斥原理] hdu 4135 Co-prime
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4135 Co-prime Time Limit: 2000/1000 MS (Java/Others) ...
- [Algorithm] 如何正确撸<算法导论>CLRS
其实算法本身不难,第一遍可以只看伪代码和算法思路.如果想进一步理解的话,第三章那些标记法是非常重要的,就算要花费大量时间才能理解,也不要马马虎虎略过.因为以后的每一章,讲完算法就是这样的分析,精通的话 ...
- [matlab] 10.最小覆盖
clear all; close all; clc; n=100; p=rand(n,2); p1=p(1,:); %取第一行的值 P1点 p2=p(2,:); %取第二行的值 P2点 r=sqrt( ...
- html js获取URL传参
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code function GetQueryString(name) { var re ...