3233. 照片

Description

Farmer John决定为他的N头排列好的奶牛(1 <= N<= 200,000)做一张全景合照。这N头奶牛分别以1..N进行编号。他一共拍了M(1<= M <=100,000)张相片,每张相片都只包含有一部分位置连续的奶牛:第i张照片涵盖着编号从a_i到b_i的所有奶牛。当然,这些照片合起来并不保证包含所有的牛。

Farmer John拍摄完所有的相片后,注意到一个很有趣的现象:他拍的每张照片中有且仅有一只奶牛身上有斑点。 FJ知道他的奶牛中有一部分是身上有斑点的,但他从来没有数过这种奶牛的数目。请根据FJ的这些照片,确定可能出现的斑点牛的最大的数目;若从FJ的照片中无法推测斑点牛的数目,则输出-1。

Input

第1行:包含两个整数N、M。

第2.. M+1.. i +1行:每行包含两个整数a_i和b_i。

Output

输出仅一行,要求输出FJ根据他的照片所能推测出的斑点牛的最大数目;若无法推测这些奶牛的数目,则输出-1。

 

Sample Input

5 3

1 4

2 5 

3 4

Sample Output

1

Data Constraint

​1 <= N<= 200,000

Solution

差分约束或者dp+单调队列优化。

 

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define F(i,a,b) for(int i=a;i<=b;i++)
#define N 200010
using namespace std;
int n,m,l[N],r[N],ma,mi,head,tail,q[N],f[N];
struct node{int x,y;}a[N];
int read(){
	int x=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*w;
}
int cmp(node a,node b){
	return a.y<b.y;
}
int main(){
	n=read();m=read();
	F(i,1,m) a[i].x=read(),a[i].y=read();
	sort(a+1,a+1+m,cmp);
	int j=1;
	F(i,1,n){
		while(a[j].y<i&&j<=m) ma=max(ma,a[j++].x);
		l[i]=ma;
	}l[n+1]=l[n];
	j=m,mi=n;
	for(int i=n;i>0;i--){
		while(a[j].y>=i&&j) mi=min(mi,a[j--].x);
		r[i]=mi;
	}
	r[n+1]=n+1;
	head=tail=1;j=0;
	F(i,1,n+1){
		while(j<i&&j<r[i]){
			if(f[j]<0){j++;continue;}
			while(head<=tail&&f[q[tail]]<f[j]) tail--;
			q[++tail]=j++;
		}
		while(head<=tail&&q[head]<l[i]) head++;
		if(head<=tail) f[i]=f[q[tail]]+(i!=n+1?1:0);
		else f[i]=-1;
	}
	printf("%d\n",f[n+1]);
	return 0;
}


作者:zsjzliziyang 
QQ:1634151125 
转载及修改请注明 
本文地址:https://blog.youkuaiyun.com/zsjzliziyang/article/details/97968629

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值