luogu 3740 [HAOI2014] 贴海报

题目

题目描述

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

张贴规则如下:

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

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

输入格式

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

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

输出格式

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

输入输出样例

输入 #1复制

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

输出 #1复制

4

说明/提示

注:图片来源:洛谷

【约束条件】

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

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

分析

一个很妙的逆向思维
如果正向思考,覆盖的时候绞尽脑汁消除覆盖,很麻烦
看最后露出来的,只要前面没挡到,就会露出来,例如:

可以存入空白,倒向操作,只要覆盖了空白的海报,就会露出来
但在离散化的时候会出错,比如:
8 3
3 6
1 3
6 7

本来是:


离散化后3与6相邻,答案本应3,输出为2,变成了:


解决方法:在离散化时,不是消去中间,而是将中间距离大于1的变为1
注意数组大小

代码

  1 /**************************
  2 User:Mandy.H.Y
  3 Language:c++
  4 Problem:luogu3740
  5 Algorithm:线段树 + 离散化
  6 **************************/
  7
  8 // 一个很妙的逆向思维
  9 //如果正向思考,覆盖的时候绞尽脑汁消除覆盖,很麻烦
 10 //看最后露出来的,只要前面没挡到,就会露出来
 11 //可以存入空白,倒向操作,只要覆盖了空白的海报,就会露出来
 12 //但在离散化的时候会出错,比如:
 13 //8 3
 14 //3 6
 15 //1 3
 16 //6 7
 17 //离散化后3与6相邻,答案本应3,输出为2
 18 //解决方法:在离散化时,不是消去中间,而是将中间距离大于1的变为1
 19 //注意数组大小
 20
 21
 22 #include<bits/stdc++.h>
 23 #define Max(x,y) ((x) > (y) ? (x) : (y))
 24 #define Min(x,y) ((x) < (y) ? (x) : (y))
 25 #define lson l,mid,k<<1
 26 #define rson mid + 1,r,k<<1|1
 27
 28 using namespace std;
 29
 30 const int maxm = 2005;
 31 int n,m,ans,judge = 0;
 32 int tree[maxm << 4];
 33
 34 struct Poster{
 35     int l,r;
 36 }pos[maxm];
 37
 38 struct Temp{
 39     int l,id;
 40     bool operator < (const Temp &a)const {
 41         return l < a.l;
 42     }
 43 }tmp[maxm << 1];
 44
 45 template<class T>inline void read(T &x) {
 46     x = 0;bool flag = 0;char ch = getchar();
 47     while(!isdigit(ch)) flag |= ch == ‘-‘,ch = getchar();
 48     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
 49     if(flag) x = -x;
 50 }
 51
 52 template<class T>void putch(const T x) {
 53     if(x > 9) putch(x / 10);
 54     putchar(x % 10 | 48);
 55 }
 56
 57 template<class T>void put(const T x) {
 58     if(x < 0) putchar(‘-‘),putch(-x);
 59     else putch(x);
 60 }
 61
 62 void file() {
 63     freopen("3740.in","r",stdin);
 64 //    freopen("2161.out","w",stdout);
 65 }
 66
 67 void readdata() {
 68     read(n);read(m);
 69 }
 70
 71 void pushup(int k){
 72     tree[k] = tree[k<<1] + tree[k<<1|1];
 73 }
 74
 75 void pushdown(int k){
 76     if(!tree[k]){
 77         tree[k<<1] = 0;
 78         tree[k<<1|1] = 0;
 79     }
 80 }
 81
 82 void buildtree(int l,int r,int k){
 83     if(l == r){
 84         tree[k] = 1;
 85         return;
 86     }
 87     int mid = (l + r) >> 1;
 88     buildtree(lson);
 89     buildtree(rson);
 90     pushup(k);
 91 }
 92
 93 void modify(int l,int r,int k,int x,int y){
 94     if(x <= l && r <= y){
 95         if(tree[k]) judge = 1;
 96         tree[k] = 0;
 97         return;
 98     }
 99     pushdown(k);
100     int mid = (l + r) >> 1;
101     if(x <= mid) modify(lson,x,y);
102     if(y > mid) modify(rson,x,y);
103     pushup(k);
104 }
105
106 void work() {
107     int cnt = 0;
108     for(int i = 1;i <= m ; ++ i){
109         read(tmp[++cnt].l);tmp[cnt].id = i;
110         read(tmp[++cnt].l);tmp[cnt].id = i;
111     }
112
113     sort(tmp + 1,tmp + cnt + 1);
114     int tot = 0;//去重 及 变为1
115     for(int i = 1;i <= cnt; ++ i){
116         int id = tmp[i].id;
117         if(tmp[i].l != tmp[i - 1].l){
118             if(tmp[i].l - tmp[i - 1].l > 1) ++tot;
119             if(pos[id].l) pos[id].r = ++tot;
120             else pos[id].l = ++tot;
121         } else {
122             if(pos[id].l) pos[id].r = tot;
123             else pos[id].l = tot;
124         }
125
126     }
127
128     buildtree(1,tot,1);
129
130     for(int i = m;i >= 1; -- i){
131         judge = 0;
132         modify(1,tot,1,pos[i].l,pos[i].r);
133         if(judge) ans++;
134     }
135     put(ans);
136 }
137
138 int main() {
139 //    file();
140     readdata();
141     work();
142     return 0;
143 }

原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11403441.html

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

luogu 3740 [HAOI2014] 贴海报的相关文章

cogs1682. [HAOI2014]贴海报 x

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

cogs 1682. [HAOI2014]贴海报 WW

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

[haoi2014]贴海报

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

洛谷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.后贴的海报可以覆盖前面已贴的海报或部分海报. 现在请你判断,张贴完所有海报后,在

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

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

题解 P3740 【[HAOI2014]贴海报】

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

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

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

JZYZOJ1537 [haoi2014]贴海报

http://172.20.6.3/Problem_Show.asp?id=1537 用的方法叫作浮水法,实质是递归自下而上判断一个区间有没有覆盖,O(n^2)感觉也没有很实用. 前几年的haoi怎么这么水啊... 代码 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<