题目大意:给定n个区间,你可以为每个区间选定一个这个区间里的数,求最长不下降子串
首先,一段子串[x,y]满足题意,当且仅当这段区间Li的最大值小于等于Ry并且[x,y-1]合法
所以我们根据单调性可以想到一种做法,把I从1到n扫一遍,记录一个指针j,代表以i为起始的最远右端点,然后每次向右扩展的时候用线段树查询一下区间最大值判断可不可行
于是TLE了
然后改成RMQ,虽然还是O(NlogN)但是常数小
然后MLE了
那就只能想O(N)做法了,我们发现他其实只是要求区间最大值,并且两个端点都是单调的,这样我们可以用一个单调队列来解决
具体看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1000010
using namespace std;
int a[N],b[N];
int q[N],h,t;
int main()
{
int n,m;
scanf("%d",&n);
int i,j,k;
for(i=1;i<=n;i++)
scanf("%d%d",&a[i],&b[i]);
j=1;
int ans=0;
a[0]=-1e9-1;b[n+1]=1e9+1;
q[1]=1;h=t=1;
for(i=1;i<=n;i++)
{
if(j==i) j=i+1;
if(q[h]==i-1) h++;
while(j<=n&&a[q[h]]<=b[j])
{
while(h<=t&&a[q[t]]<=a[j]) q[t]=0,t--;
t++;q[t]=j;
j++;
}
ans=max(ans,j-i);
}
printf("%d",ans);
}