http://main.edu.pl/en/archive/oi/18/tem
某国进行了连续n天的温度测量,测量存在误差,测量结果是第i天温度在 [li,ri] 范围内。
求最长的连续的一段,满足该段内可能温度不降。
显然,一个合法的区间是保证 li 不增,并且区间左端点的 r 小于等于区间右端点的 r 。因为显然温度的线段尽量贴着每天的L边界才能尽可能满足条件。假如我们维护完之前的一段时间,然后现在要加入第 i 天,若 Li−1>Ri ,则显然无法加入第 i 天,
假如我们现在已经知道连续的一段 [i,j−1] 是合法的,那么 [i,j] 合法,当且仅当
一种比较显然的做法就是
这样一来,我们可以从1到第n天扫整个区间序列,并维护一个 L 非增的单调队列,这样队首的元素的 L 值就是当前的合法区间里最大的那个 L 。假如当前扫到了第 i 天,就要在第 i 天入队后,维护队首,使得队首的 L 小于等于第 i 天的 R ,而 q[head−1] 是不满足 L 小于等于第 i 天的 R 这个条件的,则当前 [q[head−1]+1,i] 这段区间就是一个合法区间,并且是所有的 [k,i] 区间里最大的区间。就用 i−q[head−1] 来更新答案。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 2100000
using namespace std;
int L[MAXN],R[MAXN],n;
int q[MAXN],h=1,t=1,maxans=0;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&L[i],&R[i]);
q[t++]=1;
maxans=max(maxans,t-h);
for(int i=2;i<=n;i++)
{
while(h<t&&L[q[t-1]]<L[i]) t--;
q[t++]=i;
while(h<t&&L[q[h]]>R[i]) h++;
maxans=max(maxans,i-q[h-1]);
}
printf("%d\n",maxans);
return 0;
}