Subsequence

本文介绍了一种使用单调队列解决特定子序列问题的方法。该问题要求找出整数序列中最长的子序列,使得子序列中最大元素与最小元素之差不小于m且不大于k。通过双队列维护候选元素,实现高效求解。

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

                                       Subsequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3892    Accepted Submission(s): 1271


Problem Description
There is a sequence of integers. Your task is to find the longest subsequence that satisfies the following condition: the difference between the maximum element and the minimum element of the subsequence is no smaller than m and no larger than k.
 

 

Input
There are multiple test cases.
For each test case, the first line has three integers, n, m and k. n is the length of the sequence and is in the range [1, 100000]. m and k are in the range [0, 1000000]. The second line has n integers, which are all in the range [0, 1000000].
Proceed to the end of file.
 

 

Output
For each test case, print the length of the subsequence on a single line.
 

 

Sample Input
5 0 0
1 1 1 1 1
5 0 3
1 2 3 4 5
 

 

Sample Output
5
4
 单调队列真的有很多奥妙!
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 int z[110000],a[110000],b[110000];
 6 int main()
 7 {
 8     int n,m,k,i;
 9     while(~scanf("%d%d%d",&n,&m,&k))
10     {
11         for(i=0; i<n; i++)
12             scanf("%d",&z[i]);
13         int top1=0,top2=0,tail1=0,tail2=0,last1=-1,last2=-1,an=0;
14        for(i=0;i<n;i++)
15        {
16            while(tail1>top1&&z[a[tail1-1]]<=z[i])tail1--;
17            a[tail1++]=i;
18            while(tail2>top2&&z[b[tail2-1]]>=z[i])tail2--;
19            b[tail2++]=i;
20            while(z[a[top1]]-z[b[top2]]>k)
21            {
22                if(a[top1]<b[top2])
23                last1=a[top1++];
24                else last2=b[top2++];
25            }
26            if(z[a[top1]]-z[b[top2]]>=m)
27            {
28                an=max(an,i-max(last1,last2));
29            }
30        }
31        cout<<an<<endl;
32     }
33 }
View Code

 

 

Source

转载于:https://www.cnblogs.com/ERKE/p/3574213.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值