题意:给你n,m,k以及一数组,n个元素,求一个序列使得序列里最大值减去最小值>=m且<k,求这个序列的最大长度,序列必须连续。
思路:用单调栈维护一个单调递增序列和一个单调递减序列,计算两个单调栈的栈底元素的差值分别跟m,k 作比较得出序列的最大值。详细看代码,注释很详细
#include<stdio.h>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int a[N],maxx[N],minn[N],n,m,k;//maxx数组维护单调递减序列,存的是下标,栈底元素最大,minn数组反之
int main()
{
while(~scanf("%d%d%d",&n,&m,&k))
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
//front为头指针,tail尾指针
int front1=0,tail1=-1,front2=0,tail2=-1,flag=-1,ans=0;
for(int i=0;i<n;i++)
{
//头指针小于尾指针且当前元素大于栈顶元素时让尾指针减一,即让使栈顶元素出栈,因为要维护一个单调递减序列
while(front1<=tail1&&a[i]>a[maxx[tail1]]) tail1--;
maxx[++tail1]=i;
while(front2<=tail2&&a[i]<a[minn[tail2]]) tail2--;
minn[++tail2]=i;
//两个栈的栈顶元素,一个是存的是数组中最大的元素下标一个是数组中最小的元素下标
//用最大的减去最小的分别跟m,k比较
while(a[maxx[front1]]-a[minn[front2]]>k)
{
flag=min(maxx[front1],minn[front2]);//选择更小的下标让其++
if(flag==maxx[front1]) front1++;
if(flag==minn[front2]) front2++;
}
if(a[maxx[front1]]-a[minn[front2]]>=m)//记录答案
ans=max(ans,i-flag);
}
printf("%d\n",ans);
}
}
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