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 ...
随机推荐
- 吴裕雄 python 机器学习-Logistic(1)
import numpy as np def loadDataSet(): dataMat = [] labelMat = [] fr = open('D:\\LearningResource\\ma ...
- 弹窗切换page进行关闭
beforeRouteLeave(to,from,next){ //这里写关闭弹窗 // 这里跳转路由 MessageBox.close(); next() // next()别漏,不然不跳转 }
- Kafka日志及Topic数据清理
由于项目原因,最近经常碰到Kafka消息队列拥堵的情况.碰到这种情况为了不影响在线系统的正常使用,需要大家手动的清理Kafka Log.但是清理Kafka Log又不能单纯的去删除中间环节产生的日志, ...
- SpringBoot(十一)过滤器和拦截器
v博客前言 在做web开发的时候,过滤器(Filter)和拦截器(Interceptor)很常见,通俗的讲,过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西:拦截器可以简单理解为“拒你所想 ...
- mui-webview-子页面调用父页面的js方法
子页面// 获取当前webviewvar self = plus.webview.currentWebview();var opener = self.opener();//此句调用父页面jsopen ...
- 导出pdf
document.getElementById("exportSiteInfoTemp").onclick = function() { var thisMinheight=$(& ...
- pandas 读取大文件 read_table C-engine CParserError: Error tokenizing data
解决办法: pd_data = pd.read_table(comment_file,header=None,encoding='utf-8', engine='python') 官网解析: engi ...
- 详解 Tomcat 的连接数与线程池
前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server. ...
- heat创建stack
1.使用模板创建虚拟机 heat_template_version: 2018-09-04 description: Simple template to deploy a virtual machi ...
- python-ceilometerclient命令行(2)
命令行解析工具argparse argparse是python标准库中的模块,利用argparse,可以完成对命令行的参数定义.解析以及后续的处理.一个简单的例子: # coding:utf-8 im ...