做这题建议看一下该题的discuss。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <set>
/* 题意:给出n张海报的左端点和右端点,按顺序往墙上贴。问最后整张墙能看到几张海报。 注意:按题意是如此够造树的,即每个点其实是一小块段。
|___|___|___|___|___|___|___|___|
1 2 3 4 5 6 7 8 思路:相当于染色问题,这里我每个节点有个color值。
color值有三种情况:1.0表示该区间为染色;2.-1表示该区间含有多种颜色;3.正整数表示该区间全是一种颜色
每次更新(即第i次“涂色”)的时候,如果区间在范围内,则该区间color值替换为此次的颜色(用i表示)。
最后查询的时候,从根节点往下查,直到查询到color值为某一个正整数,标记该颜色对应的序号。
最后统计有多少个标记,即为答案。 由于数据大,要离散化,这才是重点!!!
有些人离散化,直接按顺序相邻,即每次都只加1。这是错误的!!!
给个数据就明白了:
1
3
1 10
1 3
6 10
正确答案:3
错误答案:2
忽略了顺序相邻但位置不相邻的情况
如果直接按顺序离散:
1 4
1 2
3 4
那么1 2和3 4的就会覆盖掉1 4,得出错误结果2
即离散的时候3和6之间应该还要留出一段,即总共离散为5段,不然会把中间夹的给覆盖掉了 所以离散的时候,排好序后,如果两个相邻的仅相差1,那么对应的映射+1即可。
但如果相差大于1,则对应的映射+2,留出个空隙。 在discuss里会有人说,如果按这正确的方法做,提交会WA;全部改成+1,才AC。
其实+2导致WA的原因,是数组开的不够。
我原本开的是tree[maxn<<3]的大小,用正确做法做,WA;但开大后,tree[maxn<<4],就AC了。
也就是说,POJ上其实没有这类数据 */
using namespace std;
const int maxn=;
int n,m,idx;
int maxh; //对应映射的最大值
int hash_val[]; //对应的映射
int val[maxn*]; //存储端点的值
int vis[maxn]; //用来标记颜色
//存储海报的左端点、右端点
struct Pos{
int left,right;
}pos[maxn]; struct Node{
int color; //0:该区间没有染色;-1:该区间含多种颜色;正整数:该区间涂满一种颜色。
bool lazy;
}tree[maxn<<]; //10000个海报,每个海报两个端点,所以最多会有20000个点,但开4倍不够,要开8倍,这样+2的方法才能AC void build(int rt,int L,int R){
tree[rt].color=;
tree[rt].lazy=false;
if(L==R)
return;
int mid=(L+R)>>;
build(rt<<,L,mid);
build(rt<<|,mid+,R);
} void pushUp(int rt){
int lson=rt<<,rson=rt<<|;
//只要有一个子区间上面含多种颜色(color值为-1),该节点color值为-1
if(tree[lson].color==- || tree[rson].color==-)
tree[rt].color=-;
//两个子区间都没涂有颜色
else if(!tree[lson].color && !tree[rson].color)
tree[rt].color=;
//两个子区间各自都涂有一种颜色
else if(tree[lson].color && tree[rson].color){
if(tree[lson].color==tree[rson].color)
tree[rt].color=tree[lson].color;
else
tree[rt].color=-;
}
else{
//一个为0(即该区间没有染色),另一个为正数
tree[rt].color=tree[lson].color|tree[rson].color;
}
}
void pushDown(int rt){
if(tree[rt].lazy){
int lson=rt<<,rson=rt<<|;
tree[lson].color=tree[rson].color=tree[rt].color;
tree[lson].lazy=tree[rson].lazy=true;
tree[rt].lazy=false;
}
}
void update(int rt,int l,int r,int L,int R,int color){
if(l<=L && R<=r){
tree[rt].lazy=true;
tree[rt].color=color;
return;
}
pushDown(rt);
int mid=(L+R)>>;
if(r<=mid)
update(rt<<,l,r,L,mid,color);
else if(l>mid)
update(rt<<|,l,r,mid+,R,color);
else{
update(rt<<,l,mid,L,mid,color);
update(rt<<|,mid+,r,mid+,R,color);
}
pushUp(rt);
}
void query(int rt,int L,int R){
//下面两种情况已经包含了叶子节点,因为叶子节点的color只能为0或者>0,不可能为-1。所以不会RE
if(tree[rt].color>){
//如果该区间涂有一种颜色,则标记该颜色
vis[tree[rt].color]=;
return;
}
//如果区间没有染色,直接return。
if(!tree[rt].color){
return;
}
int mid=(L+R)>>;
query(rt<<,L,mid);
query(rt<<|,mid+,R);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
idx=;
for(int i=;i<=n;i++){
scanf("%d%d",&pos[i].left,&pos[i].right);
val[idx++]=pos[i].left;
val[idx++]=pos[i].right;
}
sort(val,val+idx);
hash_val[val[]]=;
//离散
for(int i=;i<idx;i++){
if(val[i]==val[i-])
hash_val[val[i]]=hash_val[val[i-]];
//如果两个端点不相邻,则+2
else if(val[i]-val[i-]>)
hash_val[val[i]]=hash_val[val[i-]]+; //如果两个端点相邻,则+1.
else{
hash_val[val[i]]=hash_val[val[i-]]+;
}
maxh=hash_val[val[i]];
}
build(,,maxh);
for(int i=;i<=n;i++){
update(,hash_val[pos[i].left],hash_val[pos[i].right],,maxh,i);
}
memset(vis,,sizeof(vis));
query(,,maxh);
int ans=;
for(int i=;i<=n;i++){
if(vis[i]){
ans++;
}
}
printf("%d\n",ans);
}
return ;
}

POJ 2528 Mayor's posters (线段树,染色问题,离散化要注意)的更多相关文章

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

    题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...

  2. POJ 2528 Mayor’s posters (线段树段替换 && 离散化)

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

  3. POJ 2528 Mayor's posters (线段树+区间覆盖+离散化)

    题意: 一共有n张海报, 按次序贴在墙上, 后贴的海报可以覆盖先贴的海报, 问一共有多少种海报出现过. 题解: 因为长度最大可以达到1e7, 但是最多只有2e4的区间个数,并且最后只是统计能看见的不同 ...

  4. POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)

    POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...

  5. poj 2528 Mayor's posters 线段树+离散化技巧

    poj 2528 Mayor's posters 题目链接: http://poj.org/problem?id=2528 思路: 线段树+离散化技巧(这里的离散化需要注意一下啊,题目数据弱看不出来) ...

  6. poj 2528 Mayor's posters 线段树区间更新

    Mayor's posters Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=2528 Descript ...

  7. POJ 2528 Mayor's posters(线段树+离散化)

    Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...

  8. poj 2528 Mayor's posters 线段树+离散化 || hihocode #1079 离散化

    Mayor's posters Description The citizens of Bytetown, AB, could not stand that the candidates in the ...

  9. POJ 2528 Mayor's posters (线段树)

    题目链接:http://poj.org/problem?id=2528 题目大意:有一个很上的面板, 往上面贴海报, 问最后最多有多少个海报没有被完全覆盖 解题思路:将贴海报倒着想, 对于每一张海报只 ...

  10. poj 2528 Mayor's posters(线段树)

    题目:http://poj.org/problem?id=2528 题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度.现在往墙上贴N张海报,每张海报的宽度是任意的, 但是必定是单位宽度的整数 ...

随机推荐

  1. get the runing time of C++ console program.

    // 获取程序运行时间.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h"#include <time.h>#include < ...

  2. wage

    #include<iostream> using namespace std; int main() { double wage1,wage2,time; cout<<&quo ...

  3. Fedora 19 vim c语言开发环境

    1. Fedora 19 居然没有自带 gcc 和 g++: sudo yum -y install gcc gcc-c++ 2. 安装 vim 和 cvim 插件: sudo yum -y vim ...

  4. 《Apache负载均衡》RHEL6

    Apache负载均衡的搭建,基于上篇<CDN web加速代理>搭建好的服务器,我们来搭建apache负载均衡: Apahe负载均衡:就是为了缓解一台服务器的压力而多台服务器配合使用. 基于 ...

  5. server2008R2服务器开启远程

    通常我们开启远程桌面只需要在我的电脑那边把远程的打开就可以了,然后允许访问 上面说的这些其实晚上很多都有的,自己找一下,这边是自己遇到的一点问题,就是弄了很久,按网上说的弄很久,发现问题原来是在,路由 ...

  6. c#枚举自定义,用于数据绑定。

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Enum)] public ...

  7. 基础学习总结(四)---内存获取、XML之PULL解析

    外部项目引入如果没找到工程文件要先创建一个android项目在引入. 根据要查看的项目名在项目中搜索逐步查看 ==================== 内存详情获取: public class Mai ...

  8. WebApp遇到的一些坑

    一.关于js 1. 引用zepto.js时,借用插件swipe时,写的滑动加载,在ios上可以实行滑动加载数据,但是在安卓上,就是不能滑动: 注: 在使用插件的时候,要先注意其兼容性问题. 2. 用j ...

  9. 微信小程序视频地址

    微信小程序视频系列教程完整版,课程中用到的源码附在帖子最后. [url=http://bbs.larkapp.com/forum.php?mod=viewthread&tid=5673][b] ...

  10. IE6和IE7的line-height和现代浏览器不一致的问题

    1.我们发现在网页中设置line-height后,现代浏览器显示正常,可是在IE6 IE7下却不能正确解析,这时需要再额外的为旧版浏览器声明: p{ line-height: 30px; *line- ...