由于题面中给定的wall最大长度为10 000 000;若简单用线段树势必会超时。

而注意到题面中规定了输入海报的个数<=1000;因此不妨离散化,使得线段中叶节点仅含有1000个,那么线段最大深度为10,不会TLE。

同时在构造线段树的时候除了设置基本的长度变量l,r之外,

设置了一个新的变量kind用于储存当前线段的覆盖状态(=0表示没有覆盖或有多个覆盖;=1表示只有一个覆盖)。这样当计算最终状态时只需要对  遍历到的每一个kind不为0的线段  计数值加1。同时线段的搜索也在这里终止(因为若上层线段已经覆盖,那么下层必然也被覆盖,因而不需重复搜索)。

这是本题解题的关键,也是体现线段树结构特色的地方,值得好好品味,很轻巧的构造。

此外在解题中出现了两次bug:

1、sort()范围出错,由于是从1位置开始而非0位置,因此范围需要+1;

2、使用map报TLE,改为int数组后AC。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
//代码原本使用map来记录位置和编号的映射,但是TLE;改成int数组后就ac了。stl还是要慎用。
//编程思路:先想清楚算法,先实现数据结构,再写主函数
const int maxn=+;
struct line{
int l,r,kind;//这个kind的记录是精华
}tree[maxn*];//这个数量的判定 (1000的叶子,最多10层,取最大值10*maxn) int l[maxn],r[maxn];
int poster[maxn*];//记录海报的所有坐标,离散化 void build(int l,int r,int node){
tree[node].l=l,tree[node].r=r;
if(l==r)return;
int mid=(l+r)/;
build(l,mid,node*);
build(mid+,r,node*+);
} void update(int l,int r,int node,int k){
if(tree[node].l==l&&tree[node].r==r){
tree[node].kind=k;//完全覆盖
return;
}
if(tree[node].kind==k)return ;
// if(tree[node].kind!=0){//这里的细微差别个人感觉没啥影响(包括上面一行是否有必要存在的问题)
if(tree[node].kind!=&&tree[node].kind!=k){
tree[node*].kind=tree[node].kind;
tree[node*+].kind=tree[node].kind;
tree[node].kind=;
}
if(r<=tree[node*].r){
update(l,r,node*,k);
}
else if(l>=tree[node*+].l){
update(l,r,node*+,k);
}
else{
update(l,tree[node*].r,node*,k);
update(tree[node*+].l,r,node*+,k);
}
} int result=;
bool flag[maxn];
void cal(int node){
if(tree[node].kind!=){
if(flag[tree[node].kind]==false){
result++;
// cout<<tree[node].l<<" "<<tree[node].r<<" "<<tree[node].kind<<endl;//test
flag[tree[node].kind]=true;
}
}
else{
cal(node*);
cal(node*+);
}
} int pos2no[] ; int main(void){
int t;
scanf("%d",&t);
while(t--){
memset(tree,,sizeof(tree));
memset(flag,false,sizeof(flag));
memset(poster,,sizeof(poster));
memset(pos2no,,sizeof(pos2no));
int n;
scanf("%d",&n);
int j=;
for(int i=;i<=n;i++){//从1开始编号
scanf("%d%d",&l[i],&r[i]);
poster[++j]=l[i];poster[++j]=r[i];
}
sort(poster+,poster+j+);//排序去重 ;注意为什么是j+1 (wa点)
int len=j,k=;
for(int i=;i<=len;i++,k++){
poster[k]=poster[i];
while(poster[i]==poster[i+])i++;
}
int finlen=k-;
//map<int,int> pos2no;//位置到编号的映射 若使用map也是正确的,但是会报TLE,故弃之。 for(int i=;i<=finlen;i++){
pos2no[poster[i]]=i;
}
build(,finlen,) ;
for(int i=;i<=n;i++){
update(pos2no[l[i]],pos2no[r[i]],,i);
}
result=;
cal();
printf("%d\n",result);
}
return ;
}

poj_2528 Mayor's posters (线段树经典题+离散化方法)的更多相关文章

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

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

  2. POJ2528:Mayor's posters(线段树区间更新+离散化)

    Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...

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

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

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

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

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

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

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

    线段树 + 离散化 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayor ...

  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 (线段树+离散化)

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

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

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

随机推荐

  1. Openstack实现共有云多flat网络

    首先给两台虚拟机添加网卡,模式为仅主机模式 配置控制节点IP /etc/sysconfig/network-scripts/ifcfg-eth1 TYPE=Ethernet BOOTPROTO=sta ...

  2. 从外部导入数据进MySQL

    语法格式: LOAD DATA LOCAL INFILE 'E://test.txt' INTO TABLE test_table FIELDS TERMINATED BY ' ' #ENCLOSED ...

  3. zipline自制data bundles

    Databundle zipline 缺省提供了一些行情的data bundle , 可以通过 zipline bundles 查看 其中 quandl 数据源是从 https://www.quand ...

  4. 如何取option自定义属性?

    1.SELECT代码: <select name="zcdq" id="zcdq" class="easyui-validatebox" ...

  5. qemu进程页表和EPT的同步问题

    背景分析: 在之前分析EPT violation的时候,没有太注意qemu进程页表和EPT的关系,从虚拟机运行过程分析,虚拟机访存使用自身页表和EPT完成地址转换,没有用到qemu进程页表,所以也就想 ...

  6. TIOBE 9 月排行榜:C++ 式微,第 3 名被 Python 拿下

    TIOBE 发布了 9 月份的编程语言排行榜,上个月 Python 与第 3 名擦肩而过,而指数稳步上升的它在本月终于打败 C++,成功探花. ​ “人生苦短,我用 Python”,Python 的经 ...

  7. 【opencv入门篇】快速在VS上配置opencv

    环境配置:win7-32 + opencv2.4.6 + vs2013 注意:无论电脑是32位还是64位,配置opencv库目录时选择x84文件夹!因为编译都是使用32位编译:如果选用X64,则程序运 ...

  8. Jmeter(一)http接口添加header和cookie

    HTTP信息头管理器在Jmeter的使用过程中起着很重要的作用,通常我们在通过Jmeter向服务器发送http请求(get或者post)的时候,往往后端需要一些验证信息,比如说web服务器需要带过去c ...

  9. POJ2318:TOYS(叉积判断点和线段的关系+二分)&&POJ2398Toy Storage

    题目:http://poj.org/problem?id=2318 题意: 给定一个如上的长方形箱子,中间有n条线段,将其分为n+1个区域,给定m个玩具的坐标,统计每个区域中的玩具个数.(其中这些线段 ...

  10. oracle的字符集设置与乱码

    oracle的字符集设置与乱码 字符集问题一直叫人头疼,究其原因还是不能完全明白其运作原理. 在整个运行环节中,字符集在3个环节中发挥作用: 1.软件在操作系统上运作时的对用户的显示,此时采用操作系统 ...