poj2528 Mayor’s posters

题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报

思路:这题数据范围很大,直接搞超时+超内存,需要离散化:

离散化简单的来说就是只取我们需要的值来用,比如说区间[1000,2000],[1990,2012]
我们用不到[-∞,999][1001,1989][1991,1999][2001,2011][2013,+∞]这些值,所以我只需要1000,1990,2000,2012就够了,将其分别映射到0,1,2,3,在于复杂度就大大的降下来了

所以离散化要保存所有需要用到的值,排序后,分别映射到1~n,这样复杂度就会小很多很多

而这题的难点在于每个数字其实表示的是一个单位长度(并非一个点),这样普通的离散化会造成许多错误(包括我以前的代码,poj这题数据奇弱)

例子一:1-10 1-4 5-10

例子二:1-10 1-4 6-10

普通离散化后都变成了[1,4][1,2][3,4]

线段2覆盖了[1,2],线段3覆盖了[3,4],那么线段1是否被完全覆盖掉了呢?

例子一是完全被覆盖掉了,而例子二没有被覆盖

为了解决这种缺陷,我们可以在排序后的数组上加些处理,比如说[1,2,6,10]

如果相邻数字间距大于1的话,下标位置向后延一下就行了 。。。比如说6是排名第三位的,我把它排名到第四位就好了。这个原理应该不难想出来的。

为了解决这种缺陷,我们可以在排序后的数组上加些处理,比如说[1,2,6,10]

如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了.

线段树功能:update:成段替换 query:简单hash

线段树成段更新。查询的时候,实际上是二分遍历整个查询区间,每一个单位用vis来标记是否访问过。然后用D[x]来识别是否整个区间是连续的。

先不考虑离散化的问题。关于Update,我觉得本身它的Pushdown操作中携带本身题目要求的覆盖的成分,所以Pushdown是必须的。而不需要Pushup。

针对于Query操作。网上很多的题解中都没有Pushdown,这是因为本身Update的某个区间肯定和Query的某个区间是相同的,万一不同,还是需要Pushdown的,所以我写了这个操作在Query里,也是能AC的,而且我觉得是必要的。

关于离散化,由于数据范围大,查询量少。所以离散化是必要的,没什么好说的。。但是有一点,很多人忽略了完全覆盖的问题,即便是AC代码也是这样,事实上,这是因为Poj这题的数据太弱了。。。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream> using namespace std;
#define Maxn 60005
#define lx (x<<1)
#define rx ((x<<1) | 1)
#define MID ((l + r)>>1)
struct Node
{
int val;
int id;
bool operator <(const Node &a) const
{
return val<a.val || (val == a.val && id<a.id);
}
}A[Maxn];
int D[Maxn<<2];
int vis[Maxn];
int rank[Maxn];
int t,n;
void init()
{
memset(D,0,sizeof(D));
memset(vis,0,sizeof(vis));
}
void pushDown(int x)
{
if(D[x])
{
D[lx] = D[rx] = D[x];
D[x] = 0;
}
}
int query(int L,int R,int l,int r,int x)
{
if(D[x])
{
if(!vis[D[x]]) //之前可能1张海报跨了很多区间,D[X]=d D[Y]=d 这里一次性就让 vis[d] =1 了 防止多次
{
vis[D[x]] = 1;
return 1;
}
return 0;
}
//我觉得这一步是必要的。即使对于本题没有作用,但是思路上要求我们要这么做。
//pushDown(x);
if(l == r) return 0;
int ans = 0;
if(L<=MID) ans += query(L,R,l,MID,lx);
if(MID+1<=R) ans +=query(L,R,MID+1,r,rx);
return ans;
}
void update(int d,int L,int R,int l,int r,int x)//延迟更新
{
if(L<=l && r<=R)
{
D[x] = d; //注意这里==d的原因
return; //如果存在区间更小的 大区间就要往下 相当于分割的效果
}
pushDown(x);
if(L<=MID) update(d,L,R,l,MID,lx);
if(MID+1<=R) update(d,L,R,MID+1,r,rx);
}
int main()
{
#ifndef ONLINE_JUDGE #endif
scanf(" %d",&t);
while(t--)
{
scanf(" %d",&n);
n *= 2;
for(int i=0;i<n;i++)
{
scanf(" %d",&A[i].val);
A[i].id = i;
}
sort(A,A+n);
int cnt = 1;
rank[A[0].id] = cnt;
int lastValue = A[0].val;//A[i].id存的是第几个
for(int i=1;i<n;i++)
{
if(A[i].val == lastValue) rank[A[i].id] = cnt;//rank[最小的那个值]=1 但是里面存的是之前第几个
//相邻数据如果相隔大于1,Rank向后延一位
else if(A[i].val - lastValue>1)
{
++cnt;
rank[A[i].id] = ++cnt;
lastValue = A[i].val;
}
else
{
rank[A[i].id] = ++cnt;
lastValue = A[i].val;
}
}
init();
for(int i=0;i<n/2;i++) update(i+1,rank[i<<1],rank[i<<1 | 1],1,cnt,1); // (1,rank[0],rank[1]) A[].id=0/1; 找到对应的cnt
int ans = query(1,cnt,1,cnt,1);
printf("%d\n",ans);
}
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

线段树---poj2528 Mayor’s posters【成段替换|离散化】的更多相关文章

  1. 【线段树】Mayor's posters

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

  2. 线段树(单点更新and成段更新)

    线段树需要的空间. 区间为1-->n 假设是一棵完全二叉树,且树高为i. 完全二叉树性质:第i层最多有2^(i-1)个结点. 那么 2^(i-1) = n;     i = log2(n)  + ...

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

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

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

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

  5. POJ 2528.Mayor's posters-线段树(成段替换、离散数据、简单hash)

    POJ2528.Mayor's posters 这道题真的是线段数的经典的题目,因为数据很大,直接建树的话肯定不可以,所以需要将数据处理一下,没有接触离散化的时候感觉离散化这个东西相当高级,其实在不知 ...

  6. hdu1698 Just a Hook 线段树:成段替换,总区间求和

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 Problem ...

  7. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  8. poj2528 Mayor's posters(线段树之成段更新)

    Mayor's posters Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 37346Accepted: 10864 Descr ...

  9. POJ2528 Mayor's posters —— 线段树染色 + 离散化

    题目链接:https://vjudge.net/problem/POJ-2528 The citizens of Bytetown, AB, could not stand that the cand ...

随机推荐

  1. 需求:promise执行买菜做饭过程

    需求:promise执行买菜做饭过程 1.买菜 2.洗菜 3.做饭 4.吃饭 <!DOCTYPE html> <html lang="en"> <he ...

  2. No space left on device 解决 Cydia 安装应用错误

    在 Cydia 上搜索应用进行安装,提示错误:failed to write (No space left on device),从字面上的意思看是磁盘空间不够,导致写入错误,但是到 “关于” 里看到 ...

  3. JanusGraph 图数据库安装小记 ——以 JanusGraph 0.3.0 为例

    由于近期项目中有使用图数据的需求,经过对比,我们选择尝试使用 JanusGraph.本篇小记记录了我们安装 JanusGraph 以及需要一起集成的 Cassandra + Elasticsearch ...

  4. laravel5.5源码笔记(四、路由)

    今天这篇博文来探索一下laravel的路由.在第一篇讲laravel入口文件的博文里,我们就提到过laravel的路由是在application对象的初始化阶段,通过provider来加载的.这个路由 ...

  5. Hadoop系列-HDFS基础

    基本原理 HDFS(Hadoop Distributed File System)是Hadoop的一个基础的分布式文件系统,这个分布式的概念主要体现在两个地方: 数据分块存储在多台主机 数据块采取冗余 ...

  6. MIPI调试经验(转载)

    目录 一.D-PHY 1.传输模式 2.Lane States 3.Lane Levels 4.操作模式 5.时序要求 二.DSI 1.线路构成 2.两种接口的 LCD 3.数据包类型 4.从控制器到 ...

  7. ESP32 学习笔记 - Ubuntu安装

    最近买了一个ESP32的开发板,以前只玩过ESP8266,没经验只能自己一步步摸索 现在把学习的过程记录下来,以免过了一段时间就忘记了 第一步安装 VMware 可以在我的网盘下载 链接:https: ...

  8. go_json解析

    总结: 其他类型转json func Marshal(v interface{}) ([]byte, error)  json 转其他类型 func Unmarshal(data []byte, v ...

  9. 20155233 《Java程序设计》 实验三 敏捷开发与XP实践

    20155233 <Java程序设计> 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤与内容 1.在IDEA中使用工具(Code->Reformat ...

  10. 20155336 2016-2017-2 《Java程序设计》第四周学习总结

    20155336 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 第六章 继承:面向对象中,为避免多个类间重复定义共同行为.(简单说就是将相同的程序代码提升为 ...