题目链接: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线段树、离散化的更多相关文章

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

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

  2. D - Mayor's posters(线段树+离散化)

    题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...

  3. POJ2528 Mayor's posters(线段树+离散化)

    题意 : 在墙上贴海报, n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000).求出最后还能看见多少张海报. 分析 ...

  4. 【POJ 2528】Mayor’s posters(线段树+离散化)

    题目 给定每张海报的覆盖区间,按顺序覆盖后,最后有几张海报没有被其他海报完全覆盖.离散化处理完区间端点,排序后再给相差大于1的相邻端点之间再加一个点,再排序.线段树,tree[i]表示节点i对应区间是 ...

  5. poj2528 Mayor's posters (线段树+离散化)

    恩,这区间范围挺大的,需要离散化.如果TLE,还需要优化一下常数. AC代码 #include <stdio.h> #include <string.h> #include & ...

  6. Mayor's posters(线段树+离散化)

    这道题最关键的点就在离散化吧. 假如有三张海报[1, 10] [10, 13][15,  20] 仅仅三个区间就得占用到20了. 但是离散化后就可以是[1, 2] [2, 3] [4, 5] n到1e ...

  7. Mayor's posters(线段树+离散化+区间染色)

    题目链接:http://poj.org/problem?id=2528 题目: 题意:将n个区间进行染色(对于同一个区间,后一次染色会覆盖上一次的染色),问最后可见的颜色有多少种. 思路:由于区间长度 ...

  8. POJ-2528 Mayor's posters(线段树区间更新+离散化)

    http://poj.org/problem?id=2528 https://www.luogu.org/problem/UVA10587 Description The citizens of By ...

  9. POJ-2528 Mayor's posters (线段树区间更新+离散化)

    题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...

  10. poj2528(线段树+离散化)Mayor's posters

    2016-08-15 题意:一面墙,往上面贴海报,后面贴的可以覆盖前面贴的.问最后能看见几种海报. 思路:可以理解成往墙上涂颜色,最后能看见几种颜色(下面就是以涂色来讲的).这面墙长度为1~1000 ...

随机推荐

  1. 如何使用Web Service新建和更新Wiki页面的内容

    公司内部有很多部门都创建了Wiki库,来做知识共享.公司是Hosting的SharePoint环境,不能写服务器端代码,要操作Wiki只能通过Web Service来完成,所以,碰到两个情况: 1)W ...

  2. jenkins配置RF构建结果显示

    声明:转载请注明出处,谢谢 步骤1:安装robot framework plugin插件:系统管理-管理插件 步骤2:设置构建后操作:job-配置-构建后操作增加“Publish Robot Fram ...

  3. Mac上zip,rar,tar文件命令解压和压缩

    经常遇到在windowns上的压缩文件,在mac上解压出现问题,特意总结了下在Terminal里常用命令的方式解压和压缩文件 1.zip压缩文件 zip命令的参数很多,可以利用"zip -- ...

  4. 在mysql存储过程中拼接sql解决in的字段类型不匹配问题

    一个朋友问我一个问题,他写了一个存储过程,并在存储过程调用了另外一个自定义的函数.该函数返回类型如'1,34,56'的字符串,并将该字符串作为存储过程的select的id条件. begin DECLA ...

  5. $ cd `dirname $0` 和PWD用法

      在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的.因为他返回当前路径的".".这个命令写在脚本文件里才有作用,他返回这个脚本文件放置的目录,并可以根据这 ...

  6. Android——简单对话框实现

    点击一个Button,弹出一个简单的对话框: bn3.setOnClickListener(new View.OnClickListener() { public void onClick(View ...

  7. MFC 刷新函数:Invaldate,UpdateWindow,InvaldateRect

    在窗口刷新和绘制的过程中,常常需要用到窗口刷新函数.一般用于窗口图形刷新的函数有:UpdateWindows().Invaldate().InvaldateRect(). 先说UpdateWindow ...

  8. 关于 CommonJS AMD CMD UMD 规范的差异总结(转)

    根据CommonJS规范,一个单独的文件就是一个模块.每一个模块都是一个单独的作用域,也就是说,在一个文件定义的变量(还包括函数和类),都是私有的,对其他文件是不可见的. // foo.js var ...

  9. Visual Studio for Mac离线安装教程

    Visual Studio for Mac离线安装教程 可以在线安装,也可以离线安装(本次安装博主使用离线,在线安装失败了) 据说翻个墙就可以,有条件的就翻吧 没条件的我于是选择离线安装………… 离线 ...

  10. [MySQL]修改root密码的4种方法(以windows为例)

    方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...