这个题非常有意思的地方是,我们发现区间[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 区间离散化,线段树区间修改,区间询问的更多相关文章

  1. xdoj-1324 (区间离散化-线段树求区间最值)

    思想 : 1 优化:题意是覆盖点,将区间看成 (l,r)转化为( l-1,r) 覆盖区间 2 核心:dp[i]  覆盖从1到i区间的最小花费 dp[a[i].r]=min (dp[k])+a[i]s; ...

  2. POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】

    任意门:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  3. 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 ...

  4. HDU 4417.Super Mario-可持久化线段树(无修改区间小于等于H的数的个数)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. BZOJ4653(区间离散化+线段树+决策单调尺取)

    写得很好的题解 一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除.然后事实也是这样做的…… 具体起来: 1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按 ...

  6. [Noi2016]区间[离散化+线段树维护+决策单调性]

    4653: [Noi2016]区间 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 621  Solved: 329[Submit][Status][D ...

  7. poj 2528 poster经典线段树+lazy+离散化

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ; #def ...

  8. 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 ...

  9. I Hate It HDU - 1754 线段树 单点修改+区间最值

    #include<iostream> #include<cstring> using namespace std; ; int m,n,p; struct node{ int ...

  10. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

随机推荐

  1. java质数判断

    import java.util.Scanner; /** * Created by Admin on 2017/3/25. */ public class test01 { public stati ...

  2. java笔记----线程状态转换函数

    注意:stop().suspend()和 resume()方法现在已经不提倡使用,这些方法在虚拟机中可能引起“死锁”现象.suspend()和 resume()方法的替代方法是 wait()和 sle ...

  3. [20180928]如何能在11g下执行.txt

    [20180928]如何能在11g下执行.txt --//链接问的问题: http://www.itpub.net/thread-2105467-1-1.html create table test( ...

  4. Python爬虫-05:Ajax加载的动态页面内容

    1. 获取AJAX加载动态页面的内容 1.1. Introduction 如果所爬取的网址是通过Ajax方式加载的,就直接抓包,拿他后面传输数据的文件 有些网页内容使用AJAX加载,只要记得,AJAX ...

  5. 使用google的pprof工具以及在gin中集成pprof

    首先我们得先安装这两个工具: google的pprof工具链 go get -u github.com/google/pprof gin的pprof工具 go get github.com/DeanT ...

  6. nuxt拦截IE浏览器

    需求场景 判断浏览器类型,让譬如IE的低版本浏览器跳转到指定提示浏览器升级页面. 难点分析 使用过的都知道,nuxt没有暴露主入口页面也就是index.html啊,我们以前常用的IE条件判断没地方写. ...

  7. Redis 的安装 使用 通知事件

    Redis 的安装 使用 介绍: redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string.list.set.zset(sorted ...

  8. php面试题整理(四)

    应该是group by username }

  9. [matlab] 15.罚函数降维

    求非线性规划 min f(x)= x(1)^2 + x(2)^2 + 8 s.t. { x(1)^2-x(2)>=0 , -x(1) - x(2)^2 +2 = 0, x(1)>=0 ,x ...

  10. 获取列表的索引操作:enumerate

    通过循环获取列表的索引操作: 主要使用:enumerate product_list = [['Iphone7',5800], ['Coffee',30], ['疙瘩汤',10], ['Python ...