2016-08-15

题意:一面墙,往上面贴海报,后面贴的可以覆盖前面贴的。问最后能看见几种海报。

思路:可以理解成往墙上涂颜色,最后能看见几种颜色(下面就是以涂色来讲的)。这面墙长度为1~1000 0000,一千万,确实很大。暴力的话肯定不行,除非..( you know)。

正确的解法是用线段树,不过还得加上离散化,因为数据太大10000000啊。

先说一下离散化,这个其实就是压缩,把范围压缩,举个例子:

输入 :

1 3000    //涂第一种颜色 范围从1~10000      下面同理

2000 7000  //第二种颜色

我们可以先把输入的数据范围压缩,假如输入的数据存到数组a[0]=1,a[1]=3000,a[2]=2000,a[3]=7000。

离散化(压缩)过程:

先把a[]从小到大排序。然后接着

把a数组里的数据映射到dis数组里,这样涂颜色(插入)的时候用dis[a[i]]。

压缩完之后建树的时候只需建1~4范围的树,而不用建1~7000的树。所以说离散化是必须的...懂嘞谬?

离散化完事后,再说说线段树,到底是个什么树呢?

比如1~10这个线段,用二叉树的形式储存起来,

看图:

然后在每个节点加上各种信息,就可以用了,虽然空间大了但时间快了

对于这个问题 线段树主要用了三个函数

void build(int p,int a,int b) //建树

void update(int p,int col,int a,int b)//插入颜色

void query(int p)  //查询颜色

代码有详细解释

AC代码:

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std; const int MAXN=; bool tagcol[MAXN]; //标记颜色是否已经计算过 int e[MAXN<<]; //临时数组,把重复的数据去掉
int ee[MAXN][]; //直接输入数据的数组 存每张海报的范围的
int dis[]; //离散化之后的映射数组
int cnt=; //颜色计数器 struct node //线段树节点
{
int l,r; //l~r 范围
int c; //颜色(用1,2,3...表示)
}LTnode[MAXN<<]; //开数组的时候尽量开大点,开8倍就Runtime Error了,开16倍就过,虽然不知道为啥 void build(int p,int a,int b) //建树,p是节点下标,范围 a~b
{
LTnode[p].l=a;
LTnode[p].r=b;
LTnode[p].c=;
if(a==b) //到叶子节点直接返回
{
return;
} //继续递归建树
int mid=(a+b)>>;
build(p<<,a,mid);
build(p<<|,mid+,b);
return;
}
void update(int p,int col,int a,int b) //更新(插入)颜色,p是节点下标,col是颜色,a,b是要更新的范围
{
if(LTnode[p].l>=a&&LTnode[p].r<=b) //如果当前节点范围 正好在a,b内,更新颜色 返回
{
LTnode[p].c=col;
return;
}
if(LTnode[p].r<a||LTnode[p].l>b) //如果当前节点范围和a,b没有交集
return;
if(LTnode[p].c>=) //当前节点和a,b有部分交集
{
LTnode[p<<].c=LTnode[p<<|].c=LTnode[p].c; //把当前节点的颜色传递给左右孩子节点,灰常重要
LTnode[p].c=-; //-1代表有多种颜色
}
//继续处理左右孩子
update(p<<,col,a,b);
update(p<<|,col,a,b);
return;
} void query(int p) //查询,p是节点下标
{
if(LTnode[p].c==) //当前节点的颜色为0,即没有颜色
return;
if(LTnode[p].c>&&!tagcol[LTnode[p].c]) //当前节点有某种颜色并且该颜色没有被计算过
{
cnt++; //颜色计数器+1
tagcol[LTnode[p].c]=true;
return;
}
if(LTnode[p].c==-) //多色 则继续细化处理左右孩子
{
query(p<<);
query(p<<|);
}
return; } int main()
{
int T;
scanf("%d",&T);
while(T--)
{ memset(tagcol,false,sizeof(tagcol));
memset(dis,,sizeof(dis)); int n; //n表示有几张海报
//cin>>n;
scanf("%d",&n);
int maxp=;
for(int i=;i<n;i++)
{
//cin>>ee[i][0]>>ee[i][1];
scanf("%d%d",&ee[i][],&ee[i][]); //poj上用scanf就过,cin就TLE 坑啊...
if(!dis[ee[i][]]) //用dis数组先标记下 有没有重复的数据 这样就不用再开一个数组了
{
e[maxp++]=ee[i][];
dis[ee[i][]]=;
}
if(!dis[ee[i][]])
{
e[maxp++]=ee[i][];
dis[ee[i][]]=;
}
}
memset(dis,,sizeof(dis));
int has=;
sort(e,e+maxp); //先排序
for(int i=;i<maxp;i++) //for循环出来后 has 就是离散后的最大范围
{
dis[e[i]]=++has;
}
build(,,has);
for(int i=;i<n;i++) //一次插入颜色,i为颜色
{
update(,i+,dis[ee[i][]],dis[ee[i][]]);
}
cnt=;
query();
cout<<cnt<<endl; } return ;
}

手打真累啊,肩膀疼..

poj2528(线段树+离散化)Mayor's posters的更多相关文章

  1. POJ 2528 (线段树 离散化) Mayor's posters

    离散化其实就是把所有端点放在一起,然后排序去个重就好了. 比如说去重以后的端点个数为m,那这m个点就构成m-1个小区间.然后给这m-1个小区间编号1~m-1,再用线段树来做就行了. 具体思路是,从最后 ...

  2. poj2528 线段树+离散化 (倒序)

    The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign h ...

  3. 【线段树】Mayor's posters

    [poj2528]Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 66154   Accept ...

  4. POJ2528 线段树离散化

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

  5. 线段树 G - Mayor's posters 小技巧

    G - Mayor's posters POJ - 2528 这个题目要倒着来写,从后面往前面贴,因为前面的有些会被后面的覆盖. 所以我们就判断这张海报的位置有没有完全被覆盖,如果完全被覆盖了就不能贴 ...

  6. poj2528 线段树+离散化

    由于坐标可能很大,此时需要离散化,将值转化为对应的坐标. #include<stdio.h> #include<algorithm> using namespace std; ...

  7. (线段树)Mayor's posters --poj -- 2528

    链接: http://poj.org/problem?id=2528 覆盖问题, 要从后往前找, 如果已经被覆盖就不能再覆盖了,否则就可以覆盖 递归呀递归什么时候我才能吃透你 代码: #include ...

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

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

  9. POJ 2528 Mayor's posters(线段树+离散化)

    Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...

随机推荐

  1. solr在电商平台中的使用示例简析

    来源:http://blog.csdn.net/yangbutao/article/details/9450463 在电商平台中搜索是非常重要的功能,主要包括有搜索词类目导航.自动提示和搜索排序功能 ...

  2. Solr的一些查询参数

    fl: 是逗号分隔的列表,用来指定文档结果中应返回的 Field 集.默认为 “*”,指所有的字段. defType: 指定query parser,常用defType=lucene, defType ...

  3. YTU 2616: A代码完善--简易二元运算

    2616: A代码完善--简易二元运算 时间限制: 1 Sec  内存限制: 128 MB 提交: 280  解决: 187 题目描述 注:本题只需要提交填写部分的代码,请按照C++方式提交. 编写二 ...

  4. Asp.net MVC 3实例学习之ExtShop(四)——完成产品列表页

    在完成产品列表页前要做一些准备功夫.首先是去下载MvcPager用了为产品列表分页.下载的可能是基于MVC 2的,没关系,可以用在MVC 3上.如果有担心,下载源代码重新编译一次好了.下载后将DLL添 ...

  5. Hibernate HQL注入攻击入门

    SQL注入是一种大家非常熟悉的攻击方式,目前网络上有大量存在注入漏洞的DBMS(如MySQL,Oracle,MSSQL等).但是,我在网络上找不到针对Hibernate查询语言的相关资源.因此本文总结 ...

  6. 64位Ubuntu 13.04 安装Bochs 2.3.5

    bochs 2.3.5源码编译 网上编译bochs的资料非常多,基本的问题都有解决方案,我重点讲不常见的问题. 基本安装步骤 tar vxzf bochs-2.3.5.tar.gz cd bochs- ...

  7. volley(3) 参数{or_barcode:or_barcode,or_remai:or_remain, bar_remain:bar_remain} method:POST

    1. 来自于WHCombineBatchFragment.java/** * 分拆按钮点击事件,获取数据,同时获取popupWindow的数据 */private void breakingBtnCl ...

  8. [Mac][MySQL]如何启动MySQL Server

    方法来自 MySQL 5.7官方手册 http://dev.mysql.com/doc/refman/5.7/en/osx-installation-launchd.html 有两种方法,另一种是命令 ...

  9. wx处理鼠标事件

    #include "MainFrame.h" BEGIN_EVENT_TABLE(MyFrame,wxFrame) EVT_LEFT_DOWN(MyFrame::OnMouseLe ...

  10. (六)6.9 Neurons Networks softmax regression

    SoftMax回归模型,是logistic回归在多分类问题的推广,即现在logistic回归数据中的标签y不止有0-1两个值,而是可以取k个值,softmax回归对诸如MNIST手写识别库等分类很有用 ...