BZOJ 2096

本文介绍了解决BZOJ2096问题的方法,该问题要求找出序列中最长子序列,使得子序列的最大值与最小值之差不大于k。通过使用递增和递减双队列维护左右端点,实现了高效查找。

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

BZOJ 2096

【分析】
这道题就TM是个坑
给一段序列,求一段最长子序列,使序列中最大值-最小值<=k
分别用两个递增和递减的队列维护。枚举右端点,根据条件不断删除左端点,然后取min。
fffff**k

【代码】

#include<iostream>
#include<cstdio>
#include<algorithm> 
#define fo(i,j,k) for(i=j;i<=k;i++) 
using namespace std;  
const int T=3000005;  
int n,k,l1,r1,l2,r2,ans,t=1,a[T],q1[T],q2[T];  
int main()
{  
    int i;
    scanf("%d%d",&k,&n);  
    fo(i,1,n) scanf("%d", &a[i]);
    fo(i,1,n)
    {  
        while(l1<r1 && a[i]<=a[q1[r1-1]]) r1--;  
        while(l2<r2 && a[i]>=a[q2[r2-1]]) r2--;  
        q1[r1++]=q2[r2++] = i;  
        while(a[q2[l2]]-a[q1[l1]]>k)
           if(q2[l2]>q1[l1]) t=q1[l1]+1,l1++;
           else t=q2[l2]+1,l2++;  
        ans=max(ans,i-t+1);  
    }  
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值