题目描述

Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙。

张贴规则如下:

  1. electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;

  2. 所有张贴的海报的高度必须与electoral墙的高度一致的;

  3. 每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;

  4. 后贴的海报可以覆盖前面已贴的海报或部分海报。

现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。

输入输出格式

输入格式:

第一行: N M 分别表示electoral墙的长度和海报个数

接下来M行: Ai Bi 表示每张海报张贴的位置

输出格式:

输出贴完所有海报后,在electoral墙上还可以看见的海报数。


这题其实挺不错的,很典型的那种区间染色问题,所以记录一下,以便日后复习。

解法一:线段树

这种题一看就是线段树,我们选择边判断边建树,这样就省去了build和pushdown。把线段树用来存储每条线段是否全部露出来,判断的时候,如果目标线段里有一个点没有被挡住(即segtree[root]==0),那么这条海报就会露出来,ans++,然后把整条线段染色后上推,由于我们刚刚对线段树储存元素的要求,所以上推法则就是:如果一个点有一个子树有标记,那么它也有标记。记得从最上面那个海报开始判断,这样应该就没什么问题了。

#include<cstdio>
#include<iostream>
using namespace std;
int flag,sum[],i,m,n;
int a[],b[],ans;
inline void pushup(int rt){
sum[rt]=sum[rt<<]&&sum[rt<<|];
}
inline void cck(int rt,int l,int r,int x,int y){
if (sum[rt]) return;
if (x>r||y<l) return;
if (x<=l&&r<=y){
flag=; sum[rt]=;
return;
}
int mid=(l+r)>>;
if (mid>=x) cck(rt<<,l,mid,x,y);
if (mid<r) cck(rt<<|,mid+,r,x,y);
pushup(rt);
}
int main(){
scanf("%d%d",&m,&n);
m=;
for (i=; i<=n; i++){
scanf("%d%d",&a[i],&b[i]);
m=max(m,b[i]);
}
for (i=n; i>=; i--){
flag=;
cck(,,m,a[i],b[i]);
if (flag) ans++;
}
printf("%d",ans);
return ;
}

解法二:浮水法

这是一种专门解决区间染色问题的方法,思路大概是这样:

还是倒着判断,找到与海报i相交的海报j,不管他们的公共部分(因为被j挡住了),之后判断它们不相交的部分(这时i的面积变成了公共部分的面积,可能有两个公共部分,这里由递归实现),方法详见代码注释。

inline void water(int l,int r,int now,int p){ //p就是i,now用来枚举j,l,r是当前判断i的边界,a是左边界,b是右边界
   if (vis[p]) return;  //vis用于快速推出递归
while (now<=n&&(l>=b[now]||r<=a[now])) now++; //这里是判断相交
if (now>n){      //now>n则没有海报挡得住i了
ans++; vis[p]=;
return;
}
if (l<a[now]&&r>a[now]) water(l,a[now],now+,p); //不好讲,要不,自己画个图模拟一下?
if (r>b[now]&&l<b[now]) water(b[now],r,now+,p); //同上?
}

完整代码

#include<cstdio>
#include<iostream>
using namespace std;
int vis[],a[],b[];
int ans,n,m,i;
inline void water(int l,int r,int now,int p){
if (vis[p]) return;
while (now<=n&&(l>=b[now]||r<=a[now])) now++;
if (now>n){
ans++; vis[p]=;
return;
}
if (l<a[now]&&r>a[now]) water(l,a[now],now+,p);
if (r>b[now]&&l<b[now]) water(b[now],r,now+,p);
}
int main(){
scanf("%d%d",&m,&n);
for (i=; i<=n; i++){
scanf("%d%d",&a[i],&b[i]);
b[i]++;
}
vis[n]=; ans=;
for (i=n-; i>=; i--){
water(a[i],b[i],i+,i);
}
printf("%d",ans);
return ;
}

洛谷 P3740 [HAOI2014]贴海报的更多相关文章

  1. 洛谷P3740 [HAOI2014]贴海报

    题目描述 Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论.为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙. 张贴规则如下: electo ...

  2. 洛谷 3740 [HAOI2014]贴海报

    [题解] 线段覆盖问题.线段树或者并查集都可以.不离散化居然能过? #include<cstdio> #include<algorithm> #define N 1000001 ...

  3. 【题解】Luogu P3740 [HAOI2014]贴海报

    woc,今天已经是day -1了 再写一颗珂朵莉树来++rp吧 否则就要AFO了qaq 这有可能是我最后一篇题解/博客qaq 原题传送门:P3740 [HAOI2014]贴海报 考前刷水题到底是对还是 ...

  4. 洛谷P3740 【[HAOI2014]贴海报】

    (呃...本蒟蒻的第一篇题解qwq)..不废话了讲正题..思路来源于铺地毯(-->传送门)..先算出每一个格子上覆盖的海报并把可见的海报做标记然后算出有多少海报是可见的..但是作为省选题怎么可能 ...

  5. Luogu P3740 [HAOI2014]贴海报_线段树

    线段树版的海报 实际上这个与普通的线段树相差不大,只是貌似数据太水,暴力都可以过啊 本来以为要离散的,结果没打就A了 #include<iostream> #include<cstd ...

  6. BZOJ 5168 && Luogu P3740 [HAOI2014]贴海报 线段树~~

    据说某谷数据十分水...但幸好BZOJ上也过了...话说我记得讲课时讲的是奇奇怪怪的离散化..但现在突然觉得什么都可以线段树瞎搞了...QAQ 直接就是这个区间有没有被覆盖,被覆盖直接return: ...

  7. Luogu P3740 [HAOI2014] 贴海报 线段树

    线段树版的海报 实际上这个与普通的线段树相差不大,只是貌似数据太水,暴力都可以过啊 本来以为要离散的,结果没打就A了 #include<iostream> #include<cstd ...

  8. P3740 [HAOI2014]贴海报

    题目描述 Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论.为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙. 张贴规则如下: electo ...

  9. 【文文殿下】P3740 [HAOI2014]贴海报

    题解 一开始想到离散化,然后暴力模拟.但是存在一种hack数据: [5,7] [1,5] [7,9] 这样会错误的认为第一个区间被覆盖了(因为两个端点被覆盖).所以我们设置一个玄学调参系数,在一个区间 ...

随机推荐

  1. 前端-页面性能调试:Hiper

    前端-页面性能调试:Hiper   我们写单页面应用,想看页面修改后性能变更其实挺繁琐的.有时想知道是「正优化」还是「负优化」只能靠手动刷新查看network.而Hiper很好解决了这一痛点(其实Hi ...

  2. webpack 的异步组件 生成commonchunks

    new webpack.optimize.CommonsChunkPlugin({ async: 'async-common', minChunks: function (module, count) ...

  3. centos yum 安装mysql5.7 以及 默认root密码查看

    1.  首先更新rpm 从MySQL Yum仓库下载最新的rpm文件:http://dev.mysql.com/downloads/repo/yum/ (需要Oracle帐号以及填写一些使用信息,才能 ...

  4. 零基础逆向工程28_Win32_02_事件_消息_消息处理函数

    1 第一个图形界面程序 步骤1:创建Windows应用程序 选择空项目 步骤2:在新建项窗口中选C++代码文件 创建一个新的cpp文件 步骤3:在新的cpp文件中添加:#include <Win ...

  5. Spring MVC + Thymeleaf

    参考网址: https://www.cnblogs.com/litblank/p/7988689.html 一.简介 1.Thymeleaf 在有网络和无网络的环境下皆可运行,而且完全不需启动WEB应 ...

  6. javascript的常用操作(一)

    1.  实时监听input的值变化 onchange事件只在键盘或者鼠标操作改变对象属性,且失去焦点时触发,脚本触发无效; 而onkeydown/onkeypress/onkeyup在处理复制.粘贴. ...

  7. 大数四则运算java(转)

    // 大数的四则运算 #include <iostream> #include <string> #include <algorithm> using namesp ...

  8. IOS @param view 需要获取层级结构的view

    - (void)applicationDidBecomeActive:(UIApplication *)application { NSString *str = [self digView:self ...

  9. EF和linq语句查询条件不等于某个参数出现的问题

    where t.a!=字符串   这是错误的写法,正确为 where t.a!=字符串.trim() 其他类型变量需要保持实体类型和查询条件参数的类型是一致的,不然出现的语句可能会是 类似`Exten ...

  10. 使用selenium的方式获取网页中图片的链接和网页的链接,来判断是否是死链(二)

    上一篇使用Java正则表达式来判断和获取图片的链接以及跳转的网址,这篇使用selenium的自带的API(getAttribute)来获取网页中指定的内容 实现内容:获取下面所有图片的链接地址以及跳转 ...