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