[POI 2011]Temperature(单调队列)

题目链接

http://main.edu.pl/en/archive/oi/18/tem

题目大意

某国进行了连续n天的温度测量,测量存在误差,测量结果是第i天温度在 [li,ri] 范围内。
求最长的连续的一段,满足该段内可能温度不降。

思路

显然,一个合法的区间是保证 li 不增,并且区间左端点的 r 小于等于区间右端点的r。因为显然温度的线段尽量贴着每天的L边界才能尽可能满足条件。假如我们维护完之前的一段时间,然后现在要加入第 i 天,若Li1>Ri,则显然无法加入第 i 天,

假如我们现在已经知道连续的一段[i,j1]是合法的,那么 [i,j] 合法,当且仅当

maxitj1{Lt}Rj

因为显然温度的线段尽量贴着每天的L边界才能尽可能满足条件,那么到了第 j1 天时的温度显然为 maxitj1{Lt} ,若 maxitj1{Lt}>Rj ,那么无论如何都无法使得 [i,j] 合法了。

一种比较显然的做法就是

这样一来,我们可以从1到第n天扫整个区间序列,并维护一个 L 非增的单调队列,这样队首的元素的L值就是当前的合法区间里最大的那个 L 。假如当前扫到了第i天,就要在第 i 天入队后,维护队首,使得队首的L小于等于第 i 天的R,而 q[head1] 是不满足 L 小于等于第i天的 R 这个条件的,则当前[q[head1]+1,i]这段区间就是一个合法区间,并且是所有的 [k,i] 区间里最大的区间。就用 iq[head1] 来更新答案。

代码

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值