poj_2528 Mayor's posters (线段树经典题+离散化方法)
由于题面中给定的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 (线段树经典题+离散化方法)的更多相关文章
- POJ 2528 Mayor's posters (线段树区间更新+离散化)
题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...
- POJ2528:Mayor's posters(线段树区间更新+离散化)
Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...
- POJ 2528 Mayor’s posters (线段树段替换 && 离散化)
题意 : 在墙上贴海报, n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000).求出最后还能看见多少张海报. 分析 ...
- POJ 2528 Mayor's posters (线段树+区间覆盖+离散化)
题意: 一共有n张海报, 按次序贴在墙上, 后贴的海报可以覆盖先贴的海报, 问一共有多少种海报出现过. 题解: 因为长度最大可以达到1e7, 但是最多只有2e4的区间个数,并且最后只是统计能看见的不同 ...
- POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)
POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...
- [poj2528] Mayor's posters (线段树+离散化)
线段树 + 离散化 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayor ...
- POJ 2528 Mayor's posters(线段树+离散化)
Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...
- POJ 2528 Mayor's posters (线段树+离散化)
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions:75394 Accepted: 21747 ...
- poj 2528 Mayor's posters 线段树+离散化 || hihocode #1079 离散化
Mayor's posters Description The citizens of Bytetown, AB, could not stand that the candidates in the ...
随机推荐
- 【转】虚拟机下CentOS7开启SSH连接
在虚拟机(Vmware Workstation)下,安装了CentOS7,现在想通过SSH工具连接虚拟机中的CentOS7 1. 首先,要确保CentOS7安装了 openssh-server,在终 ...
- HDU2256&&HDU4565:给一个式子的求第n项的矩阵快速幂
HDU2256 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2256 题意:求(sqrt(2)+sqrt(3))^2n%1024是多少. 这个题算是h ...
- Storm-源码分析-Stats (backtype.storm.stats)
会发现, 现在storm里面有两套metrics系统, metrics framework和stats framework 并且在所有地方都是同时注册两套, 貌似准备用metrics来替代stats, ...
- mysql覆盖索引
话说有这么一个表: CREATE TABLE `user_group` ( `id` int(11) NOT NULL auto_increment, `uid` int(11) NOT NU ...
- 学习HashMap的笔记
对于HashMap只是学习了下put,remove方法,hashMap是数组+链表+红黑树组成 所以下面贴出我自己给代码的注释,看不懂的见谅哈,毕竟我也是刚了解,如果有错误的地方请指出,非常感谢 pu ...
- 《iOS Human Interface Guidelines》——Popover
弹出框 弹出框是当人们点击一个控件或屏幕上一个区域时显示的一个暂时的界面. API NOTE 在iOS 8及以后的系统中.你能够使用UIPopoverPresentationController来显示 ...
- ruamel.yaml 将字典写入yaml文件
#安装 pip install ruamel.yaml import os from ruamel import yaml # 将字典写入到yaml my_dic = { 'name': '张三', ...
- 2.AS入门教程
AndroidStudio 本文是关于androidStudio的一些基础知识 介绍 Google官方的Android集成开发环境(IDE = Integrated Development Envir ...
- thread msg
提取的nordic rf51xx/rf52xx sdk中的线程间消息通信机制,非常简洁 demo.c #include <stdio.h> #include <stdlib.h> ...
- HDU5003:Osu!(签到题)HDU5038:(签到题,题意很坑)
HDU 5003 水题,直接上代码(因为题意读错了,WA了一遍). #include <iostream> #include <string.h> #include <s ...