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 ...
随机推荐
- webpack 中使用 vue-router 注意
//render 会把el指定的容器中所有的内容都清空把#app也会去掉 都在c(app)其中的app组件中展示 所有router-link router-view要写在app这个组件里面 //A ...
- linux配置虚拟主机
linux 下怎么配置虚拟主机 linux 下怎么配置虚拟主机,在网上找到N个资料都是高手们随便说几句,都没怎么说清楚.问题: 我把域名(bs.jxiop.com)指向了 68.10.140.10 ...
- vue router 懒加载实现
在vue-cli脚手架中router文件夹中有index.js文件,里面的内容是 import Vue from 'vue'import Router from 'vue-router'import ...
- vue 父向子组件传递数据,子组件向父组件传递数据方式
父组件向子组件传递数据通过props,子组件引入到父组件中,设置一个值等于父组件的数据,通过:bind将数据传到子组件中,子组件中通过props接收父组件的数据,这样就可以使用父组件的数据了,循环组件 ...
- table-cell http://www.cnblogs.com/StormSpirit/archive/2012/10/24/2736453.html
http://www.cnblogs.com/StormSpirit/archive/2012/10/24/2736453.html
- spring ContentNegotiationManagerFactoryBean 内容协商
一.什么是内容协商 简单点说,就是同一资源,可以有多种表现形式,比如xml.json等,具体使用哪种表现形式,是可以协商的. 这是RESTfull的一个重要特性,Spring Web MVC也支持这个 ...
- JDBC的基本概念
英文名:Java DataBase Connectivity 中文名:数据库连接 作用: java操作数据库 本质上(sun公司的程序员)定义的一套操作关系型数据库的规则也就是接口,各数据库厂商实现接 ...
- Java方法的重载和重写
重载与重写对比: 重载: 权限修饰符(public private 默认):无关 方法名:重载的两个方法的方法名必须相同 形参的个数不同 形参的类型不同 三者至少满足一个 返回值类型: 重载与返回值 ...
- jms版本
Java消息服务是一个在 Java标准化组织(JCP)内开发的标准(代号JSR 914). 2001年6月25日,Java消息服务发布JMS 1.0.2b,2002年3月18日Java消息服务发布 1 ...
- html中相对(relative),绝对(absolute)位置以及float的学习和使用案例 (转)
这几天着手于CSS的研究,研究的原因主要是工作需要,最近发现如果做前端仅仅会javascript很难尽善尽美,当然懂样式和html在一定程度上可以让我们更近一步. css较为简单,由于个人擅长编写代码 ...