传送门
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
Source
2010 ACM-ICPC Multi-University Training Contest(10)——Host by HEU
Recommend
zhengfeng | We have carefully selected several similar problems for you: 3535 3529 3528 3527 3415
题目大意
给出一个序列,求最长的连续子序列,使得
M
<
=
M
a
x
−
M
i
n
<
=
K
M<=Max-Min<=K
M<=Max−Min<=K
n <= 10^5
解题思路
枚举答案系列(最长的连续子序列)的右端点
确认左端点的条件就是序列中
M
<
=
M
a
x
−
M
i
n
<
=
K
M<=Max-Min<=K
M<=Max−Min<=K
用两个单调队列分别求
M
a
x
Max
Max和
M
i
n
Min
Min
以下请配合程序食用
注意
f
f
f指左端点
f=que[h]+1
f=que1[h1]+1
(以Max举例)
为什么是
q
u
e
[
h
]
+
1
que[h]+1
que[h]+1呢
这时的
M
a
x
Max
Max的下标是1,假设现在
M
a
x
−
M
i
n
>
r
Max-Min>r
Max−Min>r,那么调小
M
a
x
Max
Max,只需将左端点调到
M
a
x
Max
Max下标的后面一位即可
序列中的
M
a
x
Max
Max就会更新
code
#include<iostream>
#include<cstdio>
using namespace std;
int n,l,r,h,t,h1,t1,a[200100],que[200100],que1[200100],ans,f;
int main(){
while(scanf("%d%d%d",&n,&l,&r)!=EOF){
h=t=h1=t1=1,ans=0,f=1;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
while(h<t&&a[que[t-1]]<a[i])t--;//递减求Max
que[t++]=i;
while(h1<t1&&a[que1[t1-1]]>a[i])t1--;//递增求Min
que1[t1++]=i;
while(h<t&&h1<t1&&a[que[h]]-a[que1[h1]]>r){//不断更改左端点,直到满足M<=Max-Min<=K
if(que[h]<que1[h1])
f=que[h]+1,h++;
else
f=que1[h1]+1,h1++;
}
if(h<t&&h1<t1&&a[que[h]]-a[que1[h1]]>=l&&i-f+1>ans)
ans=i-f+1;
}
printf("%d\n",ans);
}
}