Mayor's posters---poj2528线段树、离散化
题目链接:http://poj.org/problem?id=2528
题意:有n张海报要贴,每张需要用的区间为L到R,后面的可以贴在之前的上面,就是吧之前的挡住,求最后我们能看到几张海报;
我们可以倒着处理,因为最后贴的我们是能看到的;如果区间被贴过了result不加,没有贴过就+1并标记一下;
由于数据范围太大所以用线段树
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std; #define N 10100
#define Lson r<<1
#define Rson r<<1|1 struct Post
{
int L,R;
}p[N]; struct SegTree
{
int L, R, isCover;
int Mid()
{
return (L+R)/;
}
}a[N*]; int Hash[*N]; void Up(int r)
{
if(a[r].L!=a[r].R)
if(a[Lson].isCover== && a[Rson].isCover==)//向上更新,如果左右子树都被覆盖,那么他也会被覆盖
a[r].isCover = ;
} void BuildSegTree(int r, int L, int R)
{
a[r].isCover = ;
a[r].L = L; a[r].R = R;
if(L == R)
return ;
BuildSegTree(Lson, L, a[r].Mid());
BuildSegTree(Rson, a[r].Mid()+, R);
}
int judge(int r, int L, int R)
{
if(a[r].isCover==)
return ;//被覆盖返回0;
if(a[r].R == R && a[r].L == L)
{
a[r].isCover = ;
return ;
}
int ans;
if(L>a[r].Mid())
ans = judge(Rson, L, R);
else if(R<=a[r].Mid())
ans = judge(Lson, L, R);
else
{
int ans1 = judge(Lson, L, a[r].Mid());
int ans2 = judge(Rson, a[r].Mid()+, R);
ans = ans1 | ans2;//只要有一个没被覆盖就说明能贴;
}
Up(r);
return ans;
}
int main()
{
int T, n, k;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
k=;
for(int i=; i<=n; i++)
{
scanf("%d%d", &p[i].L, &p[i].R);
Hash[k++]=p[i].L-;//防止出现离散化后原本不相邻的数变成相邻的了
Hash[k++]=p[i].L;
Hash[k++]=p[i].R+;
Hash[k++]=p[i].R;
}
sort(Hash, Hash+k);
int len = unique(Hash, Hash+k) - Hash;
BuildSegTree(, , len);
int result = ;
for(int i=n; i>; i--)
{
int L = lower_bound(Hash, Hash+len, p[i].L) - Hash;
int R = lower_bound(Hash, Hash+len, p[i].R) - Hash; int ans=judge(, L, R);
if(ans == )
result++;
}
printf("%d\n", result);
}
return ;
}
过了那么久再写一遍
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
using namespace std; #define INF 0xfffffff
#define N 100050
#define Lson r<<1
#define Rson r<<1|1 struct SegmentTree
{
int L, R;
bool IsCover;///判断此区间是否被覆盖; int Mid() { return (L+R)>>;}
int len() { return R-L+; } } a[N<<]; void Build(int r, int L, int R)
{
a[r].L = L, a[r].R = R;
a[r].IsCover = false; if(L == R) return; Build(Lson, L, a[r].Mid());
Build(Rson, a[r].Mid()+, R); a[r].IsCover = a[Lson].IsCover && a[Rson].IsCover;
} int Query(int r, int L, int R)
{
int ans;
if(a[r].IsCover == true)
a[Lson].IsCover = a[Rson].IsCover = a[r].IsCover; if(a[r].IsCover == true)///被覆盖了,返回0;
return ;
if(a[r].L == L && a[r].R == R)///没被覆盖,把它覆盖,并返回1;
{
a[r].IsCover = true;
return ;
} if(R<=a[r].Mid())
ans = Query(Lson, L, R);
else if(L>a[r].Mid())
ans = Query(Rson, L, R);
else
{
int ans1 = Query(Lson, L, a[r].Mid());
int ans2 = Query(Rson, a[r].Mid()+, R);
ans = (ans1 || ans2);///只要有一边没被覆盖就说明能贴;
}
a[r].IsCover = a[Lson].IsCover && a[Rson].IsCover;///向上更新,因为有了这个更新所以不能在上面直接返回结果;
return ans;
} struct node
{
int L, R;
}p[N]; int Hash[N*], cnt; int main()
{
int T, n, L, R;
scanf("%d", &T);
while(T--)
{
cnt = ;
scanf("%d", &n);
for(int i=; i<=n; i++)
{
scanf("%d %d", &p[i].L, &p[i].R);
Hash[cnt++] = p[i].L; Hash[cnt++] = p[i].R;
Hash[cnt++] = p[i].L-; Hash[cnt++] = p[i].R+;
///加上左右边界是为了防止出现本身没有相连的,而离散化之后相连的情况;
}
sort(Hash, Hash+cnt);
cnt = unique(Hash, Hash+cnt)-Hash; Build(, , cnt); int ans = ; for(int i=n; i>=; i--)
{
L = lower_bound(Hash, Hash+cnt, p[i].L) - Hash;
R = lower_bound(Hash, Hash+cnt, p[i].R) - Hash;
ans += Query(, L, R);
}
printf("%d\n", ans);
}
return ;
}
Mayor's posters---poj2528线段树、离散化的更多相关文章
- poj 2528 Mayor's posters(线段树+离散化)
/* poj 2528 Mayor's posters 线段树 + 离散化 离散化的理解: 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用线段树求解的话,很明显 ...
- D - Mayor's posters(线段树+离散化)
题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...
- POJ2528 Mayor's posters(线段树+离散化)
题意 : 在墙上贴海报, n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000).求出最后还能看见多少张海报. 分析 ...
- 【POJ 2528】Mayor’s posters(线段树+离散化)
题目 给定每张海报的覆盖区间,按顺序覆盖后,最后有几张海报没有被其他海报完全覆盖.离散化处理完区间端点,排序后再给相差大于1的相邻端点之间再加一个点,再排序.线段树,tree[i]表示节点i对应区间是 ...
- poj2528 Mayor's posters (线段树+离散化)
恩,这区间范围挺大的,需要离散化.如果TLE,还需要优化一下常数. AC代码 #include <stdio.h> #include <string.h> #include & ...
- Mayor's posters(线段树+离散化)
这道题最关键的点就在离散化吧. 假如有三张海报[1, 10] [10, 13][15, 20] 仅仅三个区间就得占用到20了. 但是离散化后就可以是[1, 2] [2, 3] [4, 5] n到1e ...
- Mayor's posters(线段树+离散化+区间染色)
题目链接:http://poj.org/problem?id=2528 题目: 题意:将n个区间进行染色(对于同一个区间,后一次染色会覆盖上一次的染色),问最后可见的颜色有多少种. 思路:由于区间长度 ...
- POJ-2528 Mayor's posters(线段树区间更新+离散化)
http://poj.org/problem?id=2528 https://www.luogu.org/problem/UVA10587 Description The citizens of By ...
- POJ-2528 Mayor's posters (线段树区间更新+离散化)
题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...
- poj2528(线段树+离散化)Mayor's posters
2016-08-15 题意:一面墙,往上面贴海报,后面贴的可以覆盖前面贴的.问最后能看见几种海报. 思路:可以理解成往墙上涂颜色,最后能看见几种颜色(下面就是以涂色来讲的).这面墙长度为1~1000 ...
随机推荐
- 用Nginx做静态文件的CDN
这是上个月一次搭建多个静态文件节点的实践,转载自我的博客,欢迎交流. 鉴于监管环境和网站速度之间的矛盾,目前的网络架构方式如下:1.web动态页面(含数据库)架设在位于美国西海岸的数据中心:2.静态文 ...
- HttpClient 通信工具类
package com.taotao.web.service; import java.util.ArrayList; import java.util.List; import java.util. ...
- 给TextView加上多彩效果:改变部分字体的大小和颜色
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/18363899 前言 在实际使用中,有时候会遇到特殊需求,比如pm突发奇想,想 ...
- Linux 排错 误删 /etc/fstab 和 /boot怎样恢复
实验:在分区情况下,rm -rf /boot和/etc/fstab,恢复 首先我们查看一下/etc/fstab 里面放的是什么东西,从下图可以看出里面存放的是分区的挂载情况,删除分区将不能自动挂载 接 ...
- windows下使用git管理代码,其中出现的问题的解决办法
和朋友共同开发一个小项目,所以就涉及到了代码管理这块,刚开始想到的是使用svn,但是外网访问svn的时候需要使用花生壳来弄一个动态的域名,中间出了很多错误,感觉有点麻烦,所以就想到看看还有别的管理代码 ...
- Delphi中ClientDataSet的用法小结
Delphi中ClientDataSet的用法小结 TClientDataSet控件继承自TDataSet,其数据存储文件格式扩展名为 .cds,是基于文件型数据存储和操作的控件.该控件封装了对数据进 ...
- java(3) 面向对象
1.super关键字 * 使用super关键字调用父类的成员变量和成员方法.具体格式: super.成员变量 super.成员方法([参数1,参数2...]) * 使用super关键字调用父类的构造方 ...
- 九度OJ小结
1. 高精度问题 可参考题目 题目1137:浮点数加法 http://ac.jobdu.com/problem.php?pid=1137 对于高精度问题可以考虑使用结构体.上述为浮点数加法,因此该 ...
- 题目1208:10进制 VS 2进制(进制转换以及大数保存问题)
题目链接:http://ac.jobdu.com/problem.php?pid=1208 详细链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...
- sencha touch 在视图中显示一个html页面
Ext.define('app.view.about.About', { alternateClassName: 'about', extend: 'Ext.Container', xtype: 'a ...