【线段树】【P3740】 [HAOI2014]贴海报

传送门

Description

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

张贴规则如下:

  1. electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;
  2. 所有张贴的海报的高度必须与electoral墙的高度一致的;
  3. 每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;
  4. 后贴的海报可以覆盖前面已贴的海报或部分海报。

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

Input

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

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

Output

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

Sample Input

100 5
1 4
2 6
8 10
3 4
7 10

Sample Output

4

Hint 

  10<= N <= 10000000 1<=M<=1000 1<= Ai <= Bi <=10000000

  所有的数据都是整数。数据之间有一个空格

Solution

  考虑暴力修改 上界复杂度将达到O(nm)。显然扯淡。

  考虑进行优化。由于是对区间操作。最后输出答案也相当于对区间[1,n]进行询问,于是自然想到对区间操作最拿手的线段树。

  如果在线修改,记录区间上有几个广告,以及区间上广告是否覆盖完全(即最右侧的广告在区间外是否还有一块),合并时f[p]=f[dp]+f[ddp](+1),会产生问题:如样例图片:

          

观察样例中间被英文标出的地方,使用上述算法,改区间会被判定为有三个广告。但事实上只有两个,因为是上面覆盖了下面的一部分。

  如何解决此问题?考虑广告数量太大无法状压,但不强制在线,于是我们把广告都读进来,倒序插入。因为较早贴上的广告显然无法影响到后面的广告。这里再次使用了阶段划分和无后效性的思想。对于一个区间,如果已经被提前计算的广告完全覆盖,则直接return。一个广告能被看见,当且仅当他能覆盖一个独立的区间。至此,问题得解。

Code

#include<cstdio>
#include<algorithm>
#define ci const int
#define maxn 10000010
#define maxt 40000010

inline void qr(int &x) {
    char ch=getchar(),last=‘ ‘;
    while(ch>‘9‘||ch<‘0‘) last=ch,ch=getchar();
    while(ch>=‘0‘&&ch<=‘9‘)    x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    if(last==‘-‘)    x=-x;
}

inline int max(const int &a,const int &b) {if(a>b) return a;return b;}
inline int min(const int &a,const int &b) {if(a<b) return a;return b;}
inline int abs(const int &a) {if(a>=0) return a;return -a;}

inline void swap(int &a,int &b) {int temp=a;a=b;b=temp;}

int n,m,a,b,cnt;

bool tree[maxt],judge;

struct M {
    int l,r;
};
M MU[maxn];

void change(ci l,ci r,ci p,ci aiml,ci aimr) {
    if(l>r) return;
    if(l>aimr||r<aiml) return;
    if(l>=aiml&&r<=aimr) {if(!tree[p]) tree[p]=judge=true;return;}
    if(tree[p])    return;
    int mid=(l+r)>>1,dp=p<<1,ddp=dp|1;
    change(l,mid,dp,aiml,aimr);change(mid+1,r,ddp,aiml,aimr);
    tree[p]=tree[dp]&&tree[ddp];
}

int main() {
    qr(n);qr(m);
    for(int i=1;i<=m;++i) {qr(MU[i].l);qr(MU[i].r);}
    do {
        judge=false;
        change(1,n,1,MU[m].l,MU[m].r);
        if(judge) ++cnt;
    } while(--m);
    printf("%d\n",cnt);
    return 0;
}

Summary

  1、阶段划分是做任何题十分有力的工具,除开DP外,也要时刻应用。
  2、在线难以处理时,考虑离线。正序难以处理时,考虑倒序。无序难以处理时,考虑有序。因为后者往往在一定程度上满足无后效性。

原文地址:https://www.cnblogs.com/yifusuyi/p/9337888.html

时间: 2024-10-16 01:51:40

【线段树】【P3740】 [HAOI2014]贴海报的相关文章

洛谷P3740 [HAOI2014]贴海报

题目描述 Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论.为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙. 张贴规则如下: electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子: 所有张贴的海报的高度必须与electoral墙的高度一致的: 每张海报以"A B"表示,即从第A个格子到第B个格子张贴海报: 后贴的海报可以覆盖前面已贴的海报或部分海报. 现在请你判断,张贴完所有海报后,在electoral墙上

poj 2528(线段树+离散化) 市长的海报

http://poj.org/problem?id=2528 题目大意是市长竞选要贴海报,给出墙的长度和依次张贴的海报的长度区间(参考题目给的图),问最后你能看见的海报有几张 就是有的先贴的海报可能会被后贴的海报完全盖住,那就看不见了 这里就非常抽象的区间更新,墙的长度为建立线段树的总区间,每贴一张海报代表将这个区间的颜色涂为相应的,每张海报的颜色当然 都不相同,求最后又多少种颜色就行,但这里还要用到基础的离散化 离散化是把无限空间中无限的个体映射到有限的空间中去,以此提高算法的时空效率. 简单

P3740 [HAOI2014]贴海报 离散化+线段树

题目描述 Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论.为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙. 张贴规则如下: electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子: 所有张贴的海报的高度必须与electoral墙的高度一致的: 每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报: 后贴的海报可以覆盖前面已贴的海报或部分海报. 现在请你判断,张贴完所有海报后,在electoral墙上还可以看见

5168. [HAOI2014]贴海报【线段树】

Description Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论.为了统一管理,城市委 员 会为选民准备了一个张贴海报的electoral墙.张贴规则如下: 1.electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子: 2.所有张贴的海报的高度必须与electoral墙的高度一致的: 3.每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报: 4.后贴的海报可以覆盖前面已贴的海报或部分海报. 现在请你判断,张贴完所有海报后,在

poj 2528 Mayor&#39;s posters(线段树 离散化 区间更新 贴海报)

     这个题目本来对大神来说可能是水题, 对我就不行了,昨晚非折腾到下半夜一点 搞定, 并且可以总结出 ,只有把问题想清楚,或着看人家解题报告自己把问题和代码思路 搞清楚,才能谈的上调bug,否则根本就不知道错在哪儿.说说这个题目的理解,他是如何转化为线段树问题的呢?我们知道线段树有一个区间更新的东西,每张海报的宽度不就是一个区间么?那么我们可以用一棵树中的部分结点 来表示整张海报的可视部分,也就是说每个结点只允许表示一张完整的或着不完整的海报(好几个结点才可以表示成完整的一张海报),那么如

贴海报 (线段树染色-离散化

n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000) .求出最后还能看见多少张海报. 虽然之前学过离散化,但用的时候就想不起来 emm: 10000个海报 最多有10000个区间 20000个坐标值,远少于10000000,因此采用离散化 将离散化后的坐标对应数组下标储存到线段树中 : 染色区间是整段的,本身就可以看做 lazy标记 ,需要下推函数: 下推 : void push_down(int pos){ if( c

cogs1682. [HAOI2014]贴海报 x

1682. [HAOI2014]贴海报 ★★☆   输入文件:ha14d.in   输出文件:ha14d.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论.为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙. 张贴规则如下: 1.electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子: 2.所有张贴的海报的高度必须与electoral墙的高度一

【线段树】Mayor&#39;s posters

[poj2528]Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 66154   Accepted: 19104 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their elect

hihoCoder - 1079 - 离散化 (线段树 + 离散化)

#1079 : 离散化 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho所在的学校举办社团文化节,各大社团都在宣传栏上贴起了海报,但是贴来贴去,有些海报就会被其他社团的海报所遮挡住.看到这个场景,小Hi便产生了这样的一个疑问--最后到底能有几张海报还能被看见呢? 于是小Ho肩负起了解决这个问题的责任:因为宣传栏和海报的高度都是一样的,所以宣传栏可以被视作