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 (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
随机推荐
- 老K漫谈区块链的共识(3)——分布式系统和区块链共识
1. 啥是分布式系统 当我们评价一个新的事物或者介绍一个新的技术的时候,我们不能架空历史和环境,新的事物不可能脱离历史和环境凭空诞生.任何新的事物和新的技术总是或多或少的,与旧的事件以及过去的技术有所 ...
- oracle 压力测试工具benchmarksql
TPC-C测试 TPC-C 于 1992 年 7 月 23 日认可为新的基准测试.TPC(Transaction Processing Performance Council,事务处理性能委员会)-C ...
- 集合抽象数据类型的C语言实现
链表是实现集合的一种理想的方式.将List以typedef的方式重命名为Set.这样做能保留链表简洁的特性,还能使集合具有了一些多态的特性. 使用这种方法的最大好处就是可以使用list_next来遍历 ...
- Linux 系统出现电流音解决方案
迫于Windows 系统最近的各种故障,今天脱坑换了openSUSE Linux ,在上网途中播放视频时偶尔会出现电流音,虽然影响不大,但是还是进行了一些排查. 通过观察电流音出现时的系统负载的波段, ...
- [Java] SpringMVC工作原理之二:HandlerMapping和HandlerAdapter
一.HandlerMapping 作用是根据当前请求的找到对应的 Handler,并将 Handler(执行程序)与一堆 HandlerInterceptor(拦截器)封装到 HandlerExecu ...
- JavaScript的内置对象(Math对象)
Math对象概述 Math(算数)对象的作用是:执行常见的算数任务.保存数学公式和信息. 与我们在JavaScript 直接编写计算功能相比,Math 对象提供的计算功能执行起来要快得多. Math ...
- 在Intellij IDEA中使用Maven的方式将项目导出为jar包
前言:由于项目使用maven管理方式,所以在未发布版本的时候,就需要将项目打成jar包,供本地调试使用.注意在使用本地jar包的时候,需要将pom文件中相关jar包的依赖屏蔽,再将jar包加入项目中. ...
- Openstack window 10 镜像制作
Windows 10 Openstack 镜像制作 //************************************************************************ ...
- sqlserver 2000数据压缩解决方法
--sqlserver 2000数据压缩解决方法. /************************************************************************* ...
- centos7下安装docker(15.5容器跨主机网络--flanneld)
flannel是由CoreOS研究的一种覆盖网络(overlay network)网络工具,目的是帮助每一个host主机有一个完整的子网: 功能是:让集群中不同节点的主机创建的容器都有一个唯一的虚拟I ...