hdu 3530 单调队列水题

本文介绍了一种使用单调队列技术解决数列问题的方法,寻找满足特定条件的最小区间长度。通过构建递增和递减队列,有效地在数列中找到满足最大值减最小值位于指定范围内的最长子序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


给你一个数列找到最长的子序列   中的最大值减最小值值m   k之间



建立两个单调队列   一个递增    一个递减    当两个队首满足情况是就进行比较 找到最大值  

当不满足是旧的移动队首      怎样移???

 移动队首id较小的一个   


#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int max(int a,int b)
{
    return a>b?a:b;
}
int abs(int a)
{
    return a<0?-a:a;
}
int main()
{
    int n,m,k,i,j;
    int num[100010];
    int ma[100010],mi[100010];
    int ida[100010],idi[100010];
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        for(i=1;i<=n;i++)
        scanf("%d",&num[i]);
        int fax=0,tax=0;
        int fin=0,tin=0;
        int tt=0;
        int now=0;
        for(i=1;i<=n;i++)
        {
            while(fax<tax&&ma[tax]<=num[i]) tax--;
            ma[++tax]=num[i];
            ida[tax]=i;
            while(fin<tin&&mi[tin]>=num[i]) tin--;
            mi[++tin]=num[i];
            idi[tin]=i;
            while(ma[fax+1]-mi[fin+1]>k&&fax<tax&&fin<tin)
            {
                if(ida[fax+1]<=idi[fin+1])
                {
                    fax++;
                    now=ida[fax];
                }
                else
                {
                    fin++;
                    now=idi[fin];
                }
            }
            if(ma[fax+1]-mi[fin+1]>=m)
            tt=max(tt,i-now);
        }
        printf("%d\n",tt);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值