#20 [bzoj5168][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墙上还可以看见的海报数。

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

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

Sample Input

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

Sample Output

4

HINT

Source

思维难度:NOIP+

代码难度:NOIP

算法:线段树/堆

#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
const int Maxn=10000005;
int n,m,ans;
struct pr{
	int l,r;
}a[Maxn]; 
bool operator <(const pr &a,const pr &b){
	if(a.l!=b.l)return a.l>b.l;
	return a.r>b.r;
}
inline int mn(int x,int y){
	return x<y?x:y;
}
inline int mx(int x,int y){
	return x>y?x:y;
}
int main(){
	int u,v,nowl,nowr;
	priority_queue<pr>Q;
	scanf("%d%d",&m,&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i].l,&a[i].r);
	}
	ans=1;
	for(int i=n-1;i>=1;i--){
		bool flag=0;
		int l=a[i].l,r=a[i].r;
		while(!Q.empty())Q.pop();
		for(int j=i+1;j<=n;j++){
			Q.push(a[j]);
		}
		nowl=Q.top().l;nowr=Q.top().r;Q.pop();
		while(!Q.empty()){
			pr x0=Q.top();
			Q.pop();
			if(nowr<x0.l-1){
				if(nowl<=l&&nowr>=r){flag=1;break;}
				nowl=x0.l;
				nowr=x0.r;
				continue;
			}
			nowr=mx(nowr,x0.r);
		}
		if(flag==1)continue;
		if(nowl<=l&&nowr>=r)continue;
		ans++;
	}
	printf("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/LvYanchang/article/details/81328056
今日推荐