题目链接
题意:
n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000) 。求出最后还能看见多少张海报。

分析1

离散化:典型的区间染色问题,可以用线段树求解,但是如果直接建一般的线段树树,会超内存,而且时间复杂度相当危险,可以考虑离散化,但是又有一个坑点就是离散化会破坏区间的连续性。
比如,数据
1
3
1 4
1 1
4 4
这个答案明显是3,但是直接离散化的话答案会输出2;
因此我们再输入排序去重后,需要在临时数组里加入一条语句,之后再排一下序,最后lower_bound() 离散化

if(temp[i]-temp[i-1]>1) temp[++tot]=temp[i-1]+1; //temp[]是用于离散化的临时数组,tot是总数

这样就能解决上面例子区间丢失连续性的问题
(有可能你认为 把上面数据里的 1 1改成 1 2 会卡掉这个方法,但是这是必不可能的,因为这个方法是在已经排序去重后使用的,没有理解可以手动模拟一下);

代码

#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=100000+5;
const int inf=0x3f3f3f3f;
#define ls (i<<1)
#define rs (i<<1|1)
int tree[N<<2],lazy[N<<2];
int L[N],R[N],temp[N<<2],tot,len,ans;
bool vis[N];
void init()
{memset(tree,0,sizeof(tree) );memset(lazy,0,sizeof(lazy) );memset(vis,0,sizeof(vis) );tot=len=ans=0;
}
void pushdown(int i,int l,int r)
{lazy[ls]=lazy[rs]=lazy[i];tree[ls]=tree[rs]=lazy[i];lazy[i]=0;
}
void update(int i,int l,int r,int ll,int rr,int v)
{if(ll<=l&&r<=rr){lazy[i]=v;tree[i]=v;return;}if(lazy[i] ) pushdown(i,l,r);int mid=(l+r)>>1;if(mid>=ll) update(ls,l,mid,ll,rr,v);if(mid<rr) update(rs,mid+1,r,ll,rr,v);if(tree[ls]==tree[rs] ) tree[i]=tree[ls];elsetree[i]=-1;
}
void query(int i,int l,int r,int ll,int rr)
{if(ll<=l&&r<=rr&&tree[i]!=-1){if(tree[i]&&!vis[tree[i] ]) ans++;vis[tree[i] ]=1;return;}if(lazy[i] ) pushdown(i,l,r);int mid=(l+r)>>1;if(mid>=ll) query(ls,l,mid,ll,rr);if(mid<rr) query(rs,mid+1,r,ll,rr);
}
int read()
{int x=0,f=1;char ch=getchar();while(!isdigit(ch) ){if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch) ){x=10*x+ch-'0';ch=getchar();}return x*f;
}
int main()
{int T=read();while(T--){init();int n;n=read();for(int i=1;i<=n;i++){L[i]=read();R[i]=read();temp[++tot]=L[i];temp[++tot]=R[i];}sort(temp+1,temp+tot+1);len=unique(temp+1,temp+tot+1)-temp;int m=len;for(int i=1;i<m;i++)if(temp[i+1]-temp[i]>1) temp[++len]=temp[i]+1,tot++;sort(temp+1,temp+len+1);for(int i=1;i<=n;i++){L[i]=lower_bound(temp+1,temp+len+1,L[i] )-temp;R[i]=lower_bound(temp+1,temp+len+1,R[i] )-temp;update(1,1,len,L[i],R[i],i);}query(1,1,len,1,len);printf("%d\n",ans);}return 0;
}

分析2

浮水法:由于是从前往后覆盖,答案由后面的海报先决定,那如果我们从后往前处理,前面海报的操作便不会对后面造成影响(可以节省时间和空间),故只需通过0 1 两种状态来判断是否被覆盖,用一个标记flag,如果当前区间没被覆盖且当前区间在目标区间内,则flag=1,更新结束后ans++。

实现方法:只需要一个更新函数即可,不需要lazy延时标记。

代码

#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=10000000+5;
const int inf=0x3f3f3f3f;
#define ls (i<<1)
#define rs (i<<1|1)
bool tree[N<<2],flag;  //1表示已经被后贴的海报覆盖
int L[10005],R[10005];
void update(int i,int l,int r,int ll,int rr)
{if(tree[i]) return;  //如果后贴的海报已经覆盖if(ll<=l&&r<=rr){tree[i]=flag=1;return;}//printf("%d %d\n",l,r);int mid=(l+r)>>1;if(mid>=ll)update(ls,l,mid,ll,rr);if(mid<rr)update(rs,mid+1,r,ll,rr);tree[i]=tree[ls]&&tree[rs];
}
int read()
{int x=0,f=1;char ch=getchar();while(!isdigit(ch) ){if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch) ){x=10*x+ch-'0';ch=getchar();}return x*f;
}
int main()
{int T=read();while(T--){int n;n=read();int maxn=0;for(int i=1;i<=n;i++){L[i]=read();R[i]=read();maxn=max(maxn,R[i] );}int ans=0;for(int i=n;i>=1;i--) //浮水法,先处理最后的{flag=0;update(1,1,maxn,L[i],R[i] );// printf("%d %d %d\n",L[i],R[i],flag);if(flag) ans++;}printf("%d\n",ans);memset(tree,0,sizeof(tree) );}return 0;
}

POJ - 2528 Mayor's posters (浮水法+线段树/离散化+线段树)相关推荐

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

    题目大意 贴海报.每张海报的高度都是一样的,唯独宽度不一样.每张海报只能占用整数倍的单位线段长度,贴了 n(n<=10000) 张海报之后,有几张能够看见(有一个角能看见这张海报也算被看见了)? ...

  2. poj 2528 Mayor's posters(线段树+离散化)

    1 /* 2 poj 2528 Mayor's posters 3 线段树 + 离散化 4 5 离散化的理解: 6 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用 ...

  3. 离散化/线段树 (POJ - 2528 Mayor's posters)

    Mayor's posters https://vjudge.net/problem/POJ-2528#author=szdytom 线段树 + 离散化 讲解:https://blog.csdn.ne ...

  4. poj 2528 Mayor's posters(线段树 离散化 区间更新 贴海报)

         这个题目本来对大神来说可能是水题, 对我就不行了,昨晚非折腾到下半夜一点 搞定, 并且可以总结出 ,只有把问题想清楚,或着看人家解题报告自己把问题和代码思路 搞清楚,才能谈的上调bug,否则 ...

  5. poj 2528 Mayor's posters (线段树+离散化)

    /*离散化+线段树由于 数据的输入最大是 10000000 ,直接用开数组肯点会超,所以要将起离散话,首先 ,我们存储输入的边,将其离散化,后面的就和一般的线段树一样可. */#include< ...

  6. POJ - 2528 Mayor's posters(线段数+离散化)

    题目链接:点击查看 题目大意:给定一个长度为1e7的墙,然后给出n张海报,每张海报都会占据墙上的一部分宽度,问按照给出的次序往墙上贴海报, 最后有几张海报能露出来(露出部分也算) 题目分析:线段树的区 ...

  7. POJ 2528 Mayor's posters (离散化和线段树使用)

    还是做了线段树的题目,玩了两天也要继续看看题目了.之前就有看离散化的概念,大家可以去百度百科一下,简单转载一个例子 离散化 的大概思路 : 比如说给你一组 数据 1 4 1000 100000, 如果 ...

  8. POJ 2528 Mayor's posters 贴海报 线段树 区间更新

    注意离散化!!!线段树的叶子结点代表的是一段!!! 给出下面两个简单的例子应该能体现普通离散化的缺陷: 1-10 1-4 5-10 1-10 1-4 6-10 普通离散化算出来的结果都会是2,但是第二 ...

  9. 线段树区间染色 浮水法 学习小记 Poj 2777 + Poj 2528

    复习过的东西必须时常拿来练练,虽说都是水题.... Poj 2777 典型的区间染色问题,貌似我的写法为了不数组越界必须多开一倍的数组空间.....还没有想到解决方法,有机会参考一下别人的写法. Po ...

最新文章

  1. 无人驾驶传感器融合技术
  2. windows installer没有正确安装_电脑还可以这样禁止软件自动安装,后悔知道得太晚...
  3. css颜色跟背景总结(内含实例及截图)
  4. Scan chain/SE,SI,SO 带scan的寄存器
  5. oracle ovm配置使用
  6. 基于Python制作的一个打砖块小游戏
  7. mysql 中的neq_mysql中neq使用Python的Django框架中的压缩组件Django Compressor_MySQL
  8. 入耳式蓝牙耳机哪种音质好?微型蓝牙隐形耳机推荐
  9. macOS 环境下 Go 安装配置
  10. omnet++,veins车辆间消息的传输、车辆运动信息获取
  11. 去角质剂和磨砂膏行业调研报告 - 市场现状分析与发展前景预测
  12. Ray入门指南——分布式框架(待更新)
  13. 公众号文章和菜单栏如何直接点击拨打客服电话号码?
  14. 【ReID】Beyond Part Models: Person Retrieval with Refined Part Pooling (and A Strong Convolutional...
  15. winamp整合贴(保持最新?)
  16. 计算机毕业设计 SSM书画拍卖平台系统 拍卖管理系统 拍卖竞拍系统 网上拍卖系统Java Vue MySQL数据库 远程调试 代码讲解
  17. Firefox设置中键点击书签菜单不关闭
  18. java中把年月日时间(yyyy-MM-dd)或其他时间格式转换成只有年月(yyyy-MM)或其他时间格式的简单方法
  19. 使用PyCaret构建机器学习模型
  20. 03.Go语言的设计哲学之三: 并发

热门文章

  1. C51单片机实验——LED流水灯
  2. Numpy中的axis/axes详解
  3. 内存虚拟化、内存复用、大页内存作用及详解
  4. Oracle静态参数修改以processes为例
  5. 这些代号1024的论坛,我听得都不好意思了(突然害羞.jpg)
  6. 红外弱小目标检测之TBC-Net
  7. android版本怎么升级9.0,为什么安卓系统都升级到9.0了,而国内大部分都是Android7呢?...
  8. CVPR2020 GAN文章整理
  9. 基于CH32V307的自动浇水系统
  10. React Native version mismatch 错误