POJ2528Mayor's posters(离散化 + 线段树)
题意:给定一些高度都相同的海报去贴,问最后能看见几张海报
The picture below illustrates the case of the sample input. 
{ 8,9,10}那张被覆盖看不到,
分析:看了大神们的博客大神是一看就是线段树,可是我都知道是线段树了也不知道怎么做,真是弱的一逼;
线段树分析就是对于每一个海报所在的区间设置一个不同的数字,然后就统计有几个不同的数字即所求解,就是线段树区间更改
技巧:离散化
如果按照这个墙的宽度来设置线段树的话,很大,内存会超。考虑到海报的个数不会很多,所以根据海报的区间的两个端点来进行离散处理,
拿例子来说,{1,4} {2,6} {8,10} {3,4} {7,10} ,所以需要的点为 1, 2, 3, 4, 6, 7, 8 ,10,令x[1] = 1, x[2] = 2,x[3] = 3,x[4] = 4,x[5] = 6,x[6] = 7,x[7] = 8, x[8] = 10,就将原来大的 【 1,10】区间变成了【1,8】这就是离散化
还有一个bug,如果这组样例: {1,10} {1,3} {5,10} 就离散成了 x[1] = 1, x[2] = 3, x[3] = 5, x[4] = 10,
第一张海报时候{1,10},对于离散化后的处理时,{1,4}
第二张{1,3}, 对于离散化后的就是{1,2}
第三张{5,10},对于离散化后的就是{3,4}
对于离散化后的来统计,最后结果是2,而实际确实3,原因就是 3到5之间有4而离散化之后就把4给去掉了,这就是一个bug,处理方法就是把相邻的两个数如果差大于1就在添加一个数
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int Max = ; //根据海报的个数来设置数组
struct node
{
int l,r;
int cover; //海报的编号
int tag; //懒惰标志
};
node tree[Max * ];
int t[ * Max + ],cnt,res[Max * + ];
int a[Max + ],b[Max + ];
void buildTree(int left, int right, int k)
{
tree[k].l = left;
tree[k].r = right;
tree[k].cover = ;
tree[k].tag = -;
if(left == right)
return;
int mid = (left + right) / ;
buildTree(left, mid, k * );
buildTree(mid + , right, k * + );
}
int Find(int l, int r, int key, int temp[])
{
while(r >= l)
{
int mid = (l + r) / ;
if(temp[mid] == key)
return mid;
else if(temp[mid] > key)
{
r = mid - ;
}
else
{
l = mid + ;
}
}
return -;
}
void upDate(int left, int right, int k, int num)
{
if(tree[k].l == left && tree[k].r == right)
{
tree[k].cover = num;
tree[k].tag = num;
return;
}
if(tree[k].tag != -)
{
tree[k * ].tag = tree[k * + ].tag = tree[k].tag;
tree[k * ].cover = tree[k * + ].cover = tree[k].tag;
tree[k].tag = -;
}
int mid = (tree[k].l + tree[k].r) / ;
if(right <= mid)
{
upDate(left, right, k * , num);
}
else if(mid < left)
{
upDate(left, right, k * + , num);
}
else
{
upDate(left, mid, k * , num);
upDate(mid + , right, k * + , num);
}
}
void Search(int k)
{
if(tree[k].tag != -)
{
tree[k].cover = tree[k].tag;
tree[k * ].tag = tree[k * + ].tag = tree[k].tag;
tree[k * ].cover = tree[k * + ].cover = tree[k].tag;
tree[k].tag = -;
} if(tree[k].l == tree[k].r)
{
res[ tree[k].cover ] = ; // 看看每一个点的海报编号
return;
}
Search(k * );
Search(k * + );
}
int main()
{
int test,n;
scanf("%d", &test);
while(test--)
{
scanf("%d", &n);
cnt = ;
for(int i = ; i <= n; i++)
{
scanf("%d%d", &a[i], &b[i]);
t[ cnt++ ] = a[i];
t[ cnt++ ] = b[i]; //将所有的端点都放入t中
}
sort(t, t + cnt);
int cnt1 = ;
for(int i = ; i < cnt; i++)
{
if(t[i] != t[i - ]) //去掉相同的
t[ cnt1++ ] = t[i];
}
for(int i = cnt1 - ; i > ; i--)
{
if(t[i] - t[i - ] > ) //如果相邻数差值大于1,就则加一个数
t[ cnt1++ ] = t[i - ] + ;
}
sort(t, t + cnt1); //加完之后排序,此时已经离散完毕
for(int i = cnt1; i > ; i--)
t[i] = t[i - ];
//使区间为1到cnt1,好处理
buildTree(, cnt1, ); for(int i = ; i <= n; i++)
{
int left = Find(, cnt1, a[i], t); //二分查找出每个区间的端点在离散化后的数组中的位置
int right = Find(, cnt1, b[i], t);
upDate(left, right, , i); //更新,设置覆盖位为 i
}
memset(res, , sizeof(res));
Search(); //从根开始查找
int ans = ;
for(int i = ; i <= n; i++)
if(res[i])
ans++;
printf("%d\n", ans);
}
return ;
}
POJ2528Mayor's posters(离散化 + 线段树)的更多相关文章
- 【POJ】2528 Mayor's posters ——离散化+线段树
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Description The citizens of Bytetown, A ...
- Mayor's posters(离散化线段树)
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 54067 Accepted: 15713 ...
- POJ 2528 Mayor's posters 离散化+线段树
题目大意:给出一些海报和贴在墙上的区间.问这些海报依照顺序贴完之后,最后能后看到多少种海报. 思路:区间的范围太大,然而最多仅仅会有10000张海报,所以要离散化. 之后用线段树随便搞搞就能过. 关键 ...
- 南阳理工 题目9:posters(离散化+线段树)
posters 时间限制:1000 ms | 内存限制:65535 KB 难度:6 描述 The citizens of Bytetown, AB, could not stand that ...
- Mayor's posters (离散化线段树+对lazy的理解)
题目 题意: n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围 li,ri(1<=li<=ri<=10000000) .求出最后还能看见多少张海报. 思路: 由于 ...
- SGU 180 Inversions(离散化 + 线段树求逆序对)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...
- hpu校赛--雪人的高度(离散化线段树)
1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec 内存限制: 128 MB 提交: 81 解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...
- 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树
[BZOJ1645][Usaco2007 Open]City Horizon 城市地平线 Description Farmer John has taken his cows on a trip to ...
- 【bzoj4636】蒟蒻的数列 离散化+线段树
原文地址:http://www.cnblogs.com/GXZlegend/p/6801379.html 题目描述 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个 ...
- 离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers
题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前 ...
随机推荐
- X240s安装Win7 以及如何启用ExpressCache
新买了一台X240S笔记本,尝试了带的Win8正版一个月后,实在无法适应Win8,干脆退回Win7完事,以下为安装过程, 第一步:制作启动U盘 首先,下载一个iso格式的Win7安装镜像文件,利用微软 ...
- 东大OJ-5到100000000之间的回文质数
1217: VIJOS-P1042 时间限制: 0 Sec 内存限制: 128 MB 提交: 78 解决: 29 [提交][状态][讨论版] 题目描述 有一天,雄霸传授本人风神腿法 ...
- Python基础-字符串格式化_百分号方式_format方式
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 十天冲刺---Day5
站立式会议 站立式会议内容总结: 燃尽图 照片 PM确实不应该交给组内编码最强的人来做. 编码的过程还要考虑整个项目的流程压力较大. 需要队友的支持和沟通.
- “CEPH浅析”系列之六——CEPH与OPENSTACK
在 <"Ceph浅析"系列之二--Ceph概况>中即已提到,关注Ceph的原因之一,就是OpenStack社区对于Ceph的重视.因此,本文将对Ceph在OpenSta ...
- Java--笔记(4)
31.中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源.中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯.是连接两个独立应用程序或独立系统的软 ...
- 路由知识之ip route 命令中的疑惑
1.基础知识 1.1 路由 (Routing) 1.1.1 路由策略 (使用 ip rule 命令操作路由策略数据库) 基于策略的路由比传统路由在功能上更强大,使用更灵活,它使网络管理员不仅能够根据目 ...
- Swift微博项目--Swift中通过类名字符串创建类以及动态加载控制器的实现
Swift中用类名字符串创建类(用到了命名空间) OC中可以直接通过类名的字符串转换成对应的类来操作,但是Swift中必须用到命名空间,也就是说Swift中通过字符串获取类的方式为NSClassFro ...
- 【BZOJ 2648】SJY摆棋子 & 【BZOJ 2716】【Violet 3】天使玩偶
KDTree模板,双倍经验啦啦啦- #include<cstdio> #include<cstring> #include<algorithm> #define r ...
- dede使用方法----如何自定义字段
我们在用dede做东西的时候,有时候需要添加一些dede里面没有的字段,有dede后台里面可以添加相关的自段,下面我就以如何给产品添加一个价格的字段来讲述一下如何给dede添加字段,并且调用它. 1. ...