//poj2528贴海报(线段树离散化)
#include<cstring>
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100005; //要开10倍的数组,否则RE
bool hash[maxn];
int li[maxn],ri[maxn];
int cov[maxn<<4];
int a[maxn*3];
int cnt;
int BinSea(int key,int n) //二分查找所在的编号即离散后的位置号
{int l=0,r=n-1;while(l<=r){int mid=(l+r)/2;if(a[mid]==key) return mid;else if(a[mid]<key) l=mid+1;else r=mid-1;}return -1;
}
void Pushdown(int p) //将该区间的标记向子女节点传递
{if(cov[p]!=-1){//如果被标记cov[p<<1]=cov[p<<1|1]=cov[p];cov[p]=-1;}
}
/*
void Build(int p,int l,int r)
{cov[p]=-1;if(l==r) {return;}int mid=(l+r)/2;Build(p<<1,l,mid);Build(p<<1|1,mid+1,r);}
*/
void Update(int p,int l,int r,int x,int y,int c)
{if(x<=l&&y>=r){cov[p]=c;return;}Pushdown(p);int mid=(l+r)/2;if(x<=mid) Update(p<<1,l,mid,x,y,c);if(y>mid) Update(p<<1|1,mid+1,r,x,y,c);}void  Query(int p,int l,int r) //遍历每个区间的颜色
{if(cov[p]!=-1){if(!hash[cov[p]]){//cout<<cov[p]<<'*'<<endl;cnt++;hash[cov[p]]=true;//避免重复计数}return;}if(l==r) return;int mid=(l+r)/2;Query(p<<1,l,mid);Query(p<<1|1,mid+1,r);
}int main()
{int t,n;scanf("%d",&t);while(t--){scanf("%d",&n);int k=0;for(int i=0;i<n;i++){scanf("%d%d",&li[i],&ri[i]);a[k++]=li[i];//a[]存端点a[k++]=ri[i];}sort(a,a+k); //排序以便离散化int h=1;for(int i=1;i<k;i++) //删去相同的数{if(a[i]!=a[i-1]) a[h++]=a[i];}for(int i=h-1;i>0;i--) //距离大于1的点之间加一个数{if((a[i]-a[i-1])>1) a[h++]=a[i-1]+1;}sort(a,a+h);memset(cov,-1,sizeof(cov));//初始标记为-1for(int i=0;i<n;i++){int l=BinSea(li[i],h);int r=BinSea(ri[i],h);// cout<<l<<' '<<r<<endl;Update(1,0,h-1,l,r,i); //更新该区间包含颜色}cnt=0;memset(hash,false,sizeof(hash));Query(1,0,h-1);printf("%d\n",cnt);}return 0;
}
int binsea(int key,int n){int l=0,h=r-1;while(l<=r){int mid=(h+l)>>1;if(a[mid]==key) return mid;if(a[mid>key]) l=mid+1;else if(a[mid]<=key) r=mid-1;}return -1;
}
void down(int rt){if(lazy[rt]!=-1){lazr[rt<<1]=lazy[rt<<1|1]=laz[rt];lazy[rt]=-1;}
}
void update(int rt,int l,int r,int x,int y,int c){// Update(1,0,h-1,l,r,i); c是颜色种类if(x<=l&&r<=y){//[l,r]属于[x,y]区间  覆盖掉[l,r]区间  [x,y]是题目给的lazy[rt]=c;return;}down(rt);int mid=(l+r)/2;  if(x<=mid) Update(p<<1,l,mid,x,y,c);  if(y>mid) Update(p<<1|1,mid+1,r,x,y,c);
}
void query(int rt,int l,int r){//query(1,0,h-1)if(lazy[rt]!=-1){if(hash[lazy[rt]]==false){//初始值是false  避免重复计数cnt++;hash[lazy[rt]]==true;}return;}if(l==r) return;int mid=(l+r)/2;  Query(p<<1,l,mid);  Query(p<<1|1,mid+1,r); }

这道题与之前的题目相比重点在于一个映射的预处理,题目所给的区间达到10000000,而最多只有10000个点,如果直接建树的话太过于空旷。把这些区间的左右节点一一对应,最多有4×10000个点,远小于之前的10000000,而且区间之间的对应关系也不会改变。

举个例子: 
区间:[2,6],[4,8],[6,10] 
我们进行下面对应: 
2 4 6 8 10 
1 2 3 4 5 
则原区间变为[1,3],[2,4],[3,5]。可以发现它们之间的覆盖关系并没有改变,但是却紧凑了很多。 
但是注意对应后,应该有一个去重的操作,防止出错。

还有一点去需要注意,区间的对应稍不注意会出现颜色丢失的情况,如下: 
[1,10],–[1,4],–[6,10] 
当我们手工模拟会发现,我们只是对1,4,6,10,进行了对应,即1,2,3,4,原集合中的4,6被视为了相邻元素,所以5处的颜色丢失,最终得到了错误的结果。 
为了防止发生这种情况我们进行插值,在两个不相邻的节点间插入无关值,但是能有效的避免这种情况。

poj2528贴海报(线段树离散化)相关推荐

  1. 【POJ 2482】 Stars in Your Window(线段树+离散化+扫描线)

    [POJ 2482] Stars in Your Window(线段树+离散化+扫描线) Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  2. poj 2528 Mayor's posters(线段树+离散化)

    1 /* 2 poj 2528 Mayor's posters 3 线段树 + 离散化 4 5 离散化的理解: 6 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用 ...

  3. HDOJ 2492 Ping pong 线段树+离散化

    //2492 Ping pong 线段树+离散化 /* 题意: 有一陀人从左到右排成一排,每个人有一个唯一的技能值,每个人都找其他人比赛, 比赛前要再找一个人做裁判,裁判的技能值不能比这两个人都高,也 ...

  4. POJ2528 线段树+离散化+hash(成段更新)

    题目:Mayor's posters 题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报 思路:这题数据范围很大,直接搞超时+超内存,需要离散化: 离散化简单的来说就是只取我们需要的值来用, ...

  5. POJ-2528 Mayor's posters 线段树+离散化 或 DFS

    题目大意 有 t 组数据,每组有 n 张(1<=n<=1e4)覆盖了 区间 [li,ri] 的海报(1<=i<=n,1<=li<=ri<=1e7),海报会由于 ...

  6. 贴海报 (线段树染色-离散化

    n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000) .求出最后还能看见多少张海报. 虽然之前学过离散化,但用的时 ...

  7. poj 2528 Mayor's posters(线段树 离散化 区间更新 贴海报)

         这个题目本来对大神来说可能是水题, 对我就不行了,昨晚非折腾到下半夜一点 搞定, 并且可以总结出 ,只有把问题想清楚,或着看人家解题报告自己把问题和代码思路 搞清楚,才能谈的上调bug,否则 ...

  8. POJ Mayor's posters——线段树+离散化

    原文:http://blog.163.com/cuiqiongjie@126/blog/static/85642734201261151553308/ 大致题意: 有一面墙,被等分为1QW份,一份的宽 ...

  9. POJ 2528 Mayor's posters 贴海报 线段树 区间更新

    注意离散化!!!线段树的叶子结点代表的是一段!!! 给出下面两个简单的例子应该能体现普通离散化的缺陷: 1-10 1-4 5-10 1-10 1-4 6-10 普通离散化算出来的结果都会是2,但是第二 ...

最新文章

  1. Python第三周 学习笔记(2)
  2. vantui框架switch上显示提示文字_?Switch主机账号官网注册教程
  3. C++数据结构之链式结构
  4. 请编写一个 C 函数,该函数给出一个字节中8二进制数中为1的个数
  5. android 多态如何组件化,Android组件化之子模块之间通信方案
  6. 基于JAVA+SpringBoot+Mybatis+MYSQL的医院信息管理系统
  7. redis+mybatis+spring
  8. 如何检查字符串是否以指定的字符串开头? [重复]
  9. spring 4.x下让http请求返回json串
  10. 三 数据结构 --数和二叉树
  11. 《证券基金经营机构信息技术管理办法》要点简读
  12. 数据中心的三种布线方式(EOR/MOR/TOR)
  13. HUAWEI 机试题:相对开音节
  14. C++源文件的编译流程简介
  15. 小胖子日记之扯淡的生活2
  16. 自动驾驶|福特将在美国新建自动驾驶汽车工厂 计划未来两年投产
  17. php调用nexmo发送短信,在 Laravel 中 “规范” 的开发短信验证码发送功能
  18. OSChina 周二乱弹 ——室友开始买假发女装了
  19. 说说Laya微信小游戏适配问题
  20. IDEA注释方式快捷键

热门文章

  1. 部署tomcat环境
  2. get 和 post
  3. mongodb导入hive
  4. 电子与计算机工程 加拿大,加拿大本科热门专业:电子与计算机工程
  5. html table运用方法,HTML Table caption用法及代码示例
  6. python dataframe 计算上下两行的差值_用Python进行数据清洗!
  7. ios html 有白色边框,html – 仅在iPad上的桌子的单元格之间非常薄的白色边框
  8. Linux 环境下如何安装部署 RocketMQ 教程
  9. 如皋技校计算机老师,如皋中专计算机考试名列南通第一 共2457人参考合格率达95.5%...
  10. 初试CSS(二):选择器