https://cn.vjudge.net/problem/HDU-3530
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
思路:维护两个单点队列,q1单调非递增(最大值),q2单调非递减(最小值),线性找出该最大值和最小值所在的最大的合法区间
#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
const int N=1e5+5;
struct node{
int x,id;
}p[N];
deque<node> q1,q2;
int main(){
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k)){
q1.clear();
q2.clear();
for(int i=1;i<=n;i++){
scanf("%d",&p[i].x);
p[i].id=i;
}
int ans=0;
int pos=0;
for(int i=1;i<=n;i++){
while(!q1.empty()&&q1.back().x<p[i].x) q1.pop_back();
q1.push_back(p[i]);
while(!q2.empty()&&q2.back().x>p[i].x) q2.pop_back();
q2.push_back(p[i]);
while(q1.front().x-q2.front().x>k){
if(q1.front().id<q2.front().id){
pos=q1.front().id;
q1.pop_front();
}
else{
pos=q2.front().id;
q2.pop_front();
}
}
if(q1.front().x-q2.front().x<m) continue;
else ans=max(ans,i-pos);
}
printf("%d\n",ans);
}
return 0;
}