poj 2528(线段树+离散化) 市长的海报
http://poj.org/problem?id=2528
题目大意是市长竞选要贴海报,给出墙的长度和依次张贴的海报的长度区间(参考题目给的图),问最后你能看见的海报有几张
就是有的先贴的海报可能会被后贴的海报完全盖住,那就看不见了
这里就非常抽象的区间更新,墙的长度为建立线段树的总区间,每贴一张海报代表将这个区间的颜色涂为相应的,每张海报的颜色当然
都不相同,求最后又多少种颜色就行,但这里还要用到基础的离散化
离散化是把无限空间中无限的个体映射到有限的空间中去,以此提高算法的时空效率。
简单点说,假设区间长度有一亿甚至跟多,但是区间里具体的值却最多只用到了一百万,且不说能否开那么大的数组,也造成了
内存的浪费,所以用离散化来节省不必要的浪费
举这个题目的样例来说(前三个)
如果只是改变区间1 7 2 6 8 10的颜色,那么剩下的数字并没有用到
那么我们将这些数字排序,x[1]=1 x[2]=2 x[3]=6 x[4]=7 x[5]=8 x[6]=10
但是如果每个相邻的差值大于1的时候要插入一个数(就插入x[i]-1好了),
(如果不插的话
假设三张海报为:1 10 1 4 6 10
离散化时 x[1] = 1 x[2]=4 X[3]=6 X[4]=10
第一张海报时:墙的1~4被染为1;
第二张海报时:墙的1~2被染为2,3~4仍为1;
第三张海报时:墙的3~4被染为3,1~2仍为2。
最终,第一张海报就显示被完全覆盖了,然后输出2,但是正确答案明显是3)
插入后新的排序为x[1]=1 x[2]=2 x[3]=5 x[4]=6 x[5]=7 x[6]=8 x[7]=9 x[8]=10
然后以这个新的长度为8的数组区间建树就好
code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct point {
int l,r;
int mark,sum;
};
point tree[**],num[*];
int ans,res[*],visit[*];
void build(int i,int left,int right)
{
tree[i].l=left,tree[i].r=right;
tree[i].mark=tree[i].sum=;
if (left==right) return ;
int mid=(left+right)/;
build(i*,left,mid);
build(i*+,mid+,right);
}
void update(int i,int left,int right,int val)
{
if (left<=tree[i].l&&tree[i].r<=right){tree[i].mark=tree[i].sum=val;return ;}
if (tree[i].mark)
{
tree[i*].mark=tree[i*+].mark=tree[i].mark;
tree[i*].sum=tree[i*+].sum=tree[i].mark;
tree[i].mark=;
}
int mid=(tree[i].r+tree[i].l)/;
if (left>mid) update(i*+,left,right,val);
else if (right<=mid) update(i*,left,right,val);
else
{
update(i*,left,mid,val);
update(i*+,mid+,right,val);
}
}
int find(int i)
{
if (tree[i].l==tree[i].r)
{
if (!visit[tree[i].sum])
{
visit[tree[i].sum]=;
++ans;
}
return ans;
}
if (tree[i].mark)
{
tree[i*].mark=tree[i*+].mark=tree[i].mark;
tree[i*].sum=tree[i*+].sum=tree[i].mark;
tree[i].mark=;
}
find(i*);
find(i*+);
}
int main()
{
int t,i,n,tn,tn1,powr,powl;
scanf("%d",&t); if (t==) return ;
while (t--)
{
res[]=;
scanf("%d",&n);
for (i=;i<=n;i++)
{
scanf("%d %d",&num[i].l,&num[i].r);
if (num[i].l>num[i].r) swap(num[i].l,num[i].r);
res[++res[]]=num[i].l;
res[++res[]]=num[i].r;
}
sort(res+,res+res[]+);//离散化
tn1=tn=unique(res+,res+res[]+)-res;
for (i=;i<tn;i++)//插入数
if (res[i]-res[i-]>)
res[tn1++]=res[i]-;
res[]=tn1-;
sort(res+,res+res[]+);
build(,,res[]);//以新的区间建树
for (i=;i<=n;i++)
{
powl=lower_bound(res+,res++res[],num[i].l)-res;
powr=lower_bound(res+,res++res[],num[i].r)-res;
update(,powl,powr,i);
}
ans=;
memset(visit,,sizeof(visit));
visit[]=;
printf("%d\n",find());
} return ;
}
poj 2528(线段树+离散化) 市长的海报的更多相关文章
- poj 2528 线段树+离散化
题意:在墙上贴一堆海报(只看横坐标,可以抽象成一线段),新海报可以覆盖旧海报.求最后能看到多少张海报 sol:线段树成段更新.铺第i张海报的时候更新sg[i].x~sg[i].y这一段为i. 然而坐标 ...
- POJ 2528 (线段树 离散化) Mayor's posters
离散化其实就是把所有端点放在一起,然后排序去个重就好了. 比如说去重以后的端点个数为m,那这m个点就构成m-1个小区间.然后给这m-1个小区间编号1~m-1,再用线段树来做就行了. 具体思路是,从最后 ...
- poj 2528 线段树 离散化的小技巧
题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报思路:直接搞超时+超内存,需要离散化.离散化简单的来说就是只取我们需要的值来 用,比如说区间[1000,2000],[1990,2012] ...
- Mayor's posters POJ - 2528(线段树 + 离散化)
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 74745 Accepted: 21574 ...
- poj 2528 线段树区间修改+离散化
Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...
- Mayor's posters POJ - 2528 线段树(离散化处理大数?)
题意:输入t组数据,输入n代表有n块广告牌,按照顺序贴上去,输入左边和右边到达的地方,问贴完以后还有多少块广告牌可以看到(因为有的被完全覆盖了). 思路:很明显就是线段树更改区间,不过这个区间的跨度有 ...
- Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长
参考 https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html #include <stdio.h> #include ...
- Mayor's posters POJ - 2528 线段树区间覆盖
//线段树区间覆盖 #include<cstdio> #include<cstring> #include<iostream> #include<algori ...
- POJ 2528 线段树
坑: 这道题的坐标轴跟普通的坐标轴是不一样的-- 此题的坐标轴 标号是在中间的-- 线段树建树的时候就不用[l,mid][mid,r]了(这样是错的) 直接[l,mid][mid+1,r]就OK了 D ...
随机推荐
- RMI 、RPC和SOAP
- 最小生成树一·Prim算法
描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问题也接踵而来——小Hi现在手上拥有N座城市,且已知这N座城市中任意两座城市之间建造道 ...
- BOS物流项目第十三天
教学计划 1.Quartz概述 a. Quartz介绍和下载 b. 入门案例 c. Quartz执行流程 d. cron表达式 2.在BOS项目中使用Quartz创建定时任务 3.在BOS项目中使用J ...
- centos最小安装之后无法使用ifconfig
Centos7安装之后,无法使用ifconfig(找不到命令) 运行 yum install provides 再安装net-tools即可 yum install net-tools 没有网,下载r ...
- 自定义sql server 聚合涵数
using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Micr ...
- spring boot 中使用 Redis 与 Log
spring boot + mybatis + redis 配置 1.application.yml #配置访问的URLserver: servlet-path: /web port: spring: ...
- 【OpenGL】第一个窗口
包含头文件: #include <GL/glew.h> // GLFW #include <GLFW/glfw3.h> 初始化与配置GLFW: glfwInit(); //初始 ...
- 搭建harbor仓库、LDAP认证
ldap: 192.168.199.177 c5game.com 宿主机:192.168.199.224 测试客户机:192.168.199.223 安装docker.docker-compose 访 ...
- cf-Round551-Div2-D. Serval and Rooted Tree(DP)
题目链接:https://codeforces.com/contest/1153/problem/D 题意:有一棵树,给定结点数n,在每个结点上的操作(max:表示该结点的number为其孩子结点中的 ...
- (转)FFMPEG filter使用实例(实现视频缩放,裁剪,水印等)
本文转载自http://blog.csdn.net/li_wen01/article/details/62442162 FFMPEG官网给出了FFMPEG 滤镜使用的实例,它是将视频中的像素点替换成字 ...