题目网址:http://poj.org/problem?id=2528

题意:

  n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。

求出最后还能看见多少张海报。

  输入:

 1
 5
 1 4
 2 6
 8 10
 3 4
 7 10
 这题用常规思路解题必定TLE,l,r太大;

通俗点说,离散化就是压缩区间,使原有的长区间映射到新的短区间,但是区间压缩前后的覆盖关系不变。举个例子:

有一条1到10的数轴(长度为9),给定4个区间[2,4] [3,6] [8,10] [6,9],覆盖关系就是后者覆盖前者,每个区间染色依次为 1 2 3 4。

现在我们抽取这4个区间的8个端点,2 4 3 6 8 10 6 9

然后删除相同的端点,这里相同的端点为6,则剩下2 4 3 6 8 10 9

对其升序排序,得2 3 4 6 8 9 10

然后建立映射

2     3     4     6     8     9   10

↓     ↓      ↓     ↓     ↓     ↓     ↓

1     2     3     4     5     6     7

那么新的4个区间为 [1,3] [2,4] [5,7] [4,6],覆盖关系没有被改变。新数轴为1到7,即原数轴的长度从9压缩到6,显然构造[1,7]的线段树比构造[1,10]的线段树更省空间,搜索也更快,但是求解的结果却是一致的。

离散化时有一点必须要注意的,就是必须先剔除相同端点后再排序,这样可以减少参与排序元素的个数,节省时间。

 #include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define N 10100
#define M 10000000
bool vis[*N];//标记出现过得海报
int x[*N];
struct T
{
int node,add,l,r;
}tree[M*];
void creat(int l,int r,int k)//建树
{
tree[k].node=;
tree[k].l=l;
tree[k].r=r;
tree[k].add=;
if(l==r)
return;
int mid=(l+r)>>;
creat(l,mid,k<<);
creat(mid+,r,k<<|);
}
void pushdown(int k,int color)//延迟标记
{
int x=k<<;
tree[x].add=;
tree[x+].add=;
tree[x].node=color;
tree[x+].node=color;
tree[k].add=;
tree[k].node=;
}
void Search(int l,int r,int color,int k)//更新线段树
{
if(r<tree[k].l||l>tree[k].r)
return ;
if(l<=tree[k].l&&r>=tree[k].r)
{
tree[k].node=color;
tree[k].add=;
return ;
}
if(tree[k].add)
pushdown(k,tree[k].node);
int mid=(tree[k].l+tree[k].r)>>;
if(r<=mid)
Search(l,r,color,k<<);
else if(l>mid)
Search(l,r,color,k<<|);
else
{
Search(l,mid,color,k<<);
Search(mid+,r,color,k<<|);
}
}
int ans;
void q(int l,int r,int k)//查找不同颜色的区域
{
if(tree[k].add)
{
if(!vis[tree[k].node])
{
ans++;
vis[tree[k].node]=;
}
return ;
}
int mid=(l+r)>>;
q(l,mid,k<<);
q(mid+,r,k<<|);
}
int s(int l,int r,int k)//二分查找
{
int mid;
while(l<=r)
{
mid=(l+r)>>;
if(k<x[mid]) r=mid-;
else if(k>x[mid]) l=mid+;
else return mid;
}
return -;
}
int main()
{
int t,n,i,j;
int l[N],r[N];
scanf("%d",&t);
while(t--)
{
j=;
memset(vis,,sizeof(vis));
scanf("%d",&n);
for(i=;i<n;i++)
{
scanf("%d%d",&l[i],&r[i]);
x[j++]=l[i];
x[j++]=r[i];
}
sort(x,x+j);
int m=;
for(i=;i<j-;i++)
{
if(x[i]==x[i+])
{
m--;
}
else
{
x[i+m]=x[i+];
}
}
j=j+m-;
sort (x,x+j);
/*for(i=0;i<n;i++)
{
printf("%d %d ",s(0,j-1,l[i])+1,s(0,j-1,r[i])+1);
cout<<endl;
}*/
creat(,j,);
for(i=;i<n;i++)
{
Search(s(,j-,l[i])+,s(,j-,r[i])+,i+,);
}
ans=;
q(,j,);
printf("%d\n",ans);
}
return ;
}

poj2528线段树解题报告,离散化+线段树的更多相关文章

  1. 【九度OJ】题目1172:哈夫曼树 解题报告

    [九度OJ]题目1172:哈夫曼树 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1172 题目描述: 哈夫曼树,第一行输入一个数n, ...

  2. [POJ2528]Mayor's posters(离散化+线段树)

    Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 70365   Accepted: 20306 ...

  3. hdu 1754 I Hate It 解题报告(线段树 代码+注释)

    题目链接:传送门 I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  4. 洛谷 P3924 康娜的线段树 解题报告

    P3924 康娜的线段树 题目描述 小林是个程序媛,不可避免地康娜对这种人类的"魔法"产生了浓厚的兴趣,于是小林开始教她\(OI\). 今天康娜学习了一种叫做线段树的神奇魔法,这种 ...

  5. [jzoj 6086] [GDOI2019模拟2019.3.26] 动态半平面交 解题报告 (set+线段树)

    题目链接: https://jzoj.net/senior/#main/show/6086 题目: 题解: 一群数字的最小公倍数就是对它们质因数集合中的每个质因数的指数取$max$然后相乘 这样的子树 ...

  6. 「ZJOI2019」线段树 解题报告

    「ZJOI2019」线段树 听说有人喷这个题简单,然后我就跑去做,然后自闭感++,rp++(雾) 理性分析一波,可以发现最后形成的\(2^k\)个线段树,对应的操作的一个子集,按时间顺序作用到这颗线段 ...

  7. OrzFAng系列–树 解题报告

    题目描述 方方方种下了三棵树,两年后,第二棵树长出了n个节点,其中1号节点是根节点. 给定一个n个点的树 支持两种操作 方方方进行m次操作,每个操作为: (1)给出两个数i,x,将第i个节点的子树中, ...

  8. [BZOJ1984]月下“毛景树”解题报告|树链剖分

    Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里.爬啊爬~爬啊爬~~毛毛虫爬到了一颗小小的“毛景树” ...

  9. 「HNOI2016」树 解题报告

    「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...

随机推荐

  1. Hough变换的基本思考

    一,概念: Hough变换用于在图像中检测特定性状,如线,圆,矩形等,广泛用于图像识别领域. 二,原理: 1,Hough变换直线检测: 一条直接的方程可表示为:y = a*x + b ,当a,b固定时 ...

  2. JavaScript HTML DOM增删改查

    首先 js 可以修改HTML中的所有元素和属性,它还可以改变CSS样式,并且可以监听到所有事件并作出响应,这篇笔记呢 主要记录如何对HTML元素进行增删改查. 1 查找DOM 第一种方式是我们最常用的 ...

  3. Android 百度语音合成集成

    一.环境配置: 下载资料:http://ai.baidu.com/sdk 官方视频讲解:http://ai.baidu.com/support/video 接入指南:http://ai.baidu.c ...

  4. 不通过AppStore,在iOS设备上直接安装应用程序的原理

    本文转载至  http://mobile.51cto.com/hot-439095.htm 通过itms-services协议,可以通过safari浏览器直接在iOS设备上安装应用程序.利用这种方式, ...

  5. 错误命令“if not exist "\Dll" mkdir "\Dll" xcopy "\bin\Debug\*.*" "F:\647\VS项目\EtrolMes2014SY\Framework\Dll" /e /i /y”已退出,代码为 9009

    分析错误 第一步:观察错误,发现plugin文件夹中未生成对应的编译文件. 第二步:XCOPY命令无法执行,百度xcopy为何无法执行 第三步,搜索,发现环境变量未配置正确. 就是环境变量path(大 ...

  6. ST表(离线RMQ)

    离线RAQ时,预处理为O(n*lgn),查询为O(1)的算法,比较有意思的一种算法 放个模板在这可以随时看 //ST表(离线) //预处理 O(n*lgn) , 查询 O(1) #include &l ...

  7. 【python】-- Django Form

    Django  Form Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容(自定义样式) 一.F ...

  8. 基础篇-java开发

    开局必知 1.变量 在java中,以{}为作用域,所以就存在成员变量和局部变量之说 由于java是强类型语言,所以在申明变量的时候,必须指定类型 java里,一个变量有声明过程和初始化过程(也就是赋值 ...

  9. android 支付宝集成 使用常见错误

    版权声明:好记星不如烂笔头,欢迎批判转载 https://blog.csdn.net/ab601026460/article/details/34956365 1:自己近期在做了支付.遇到了一下问题先 ...

  10. Android Studio工程引用第三方so文件

    应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库.在Androi ...