题意:给n个数和m,k,问你数列中最长的子序列,其中最大值减去最小值大于等于m小于等于k
思路:想着想着想到尺取去了,写了一半实现不了((/ □ \))。维护了两个队列,一个是以当前结束所构成的递减序列的位置,另一个是以当前结束构成的递增序列的位置,然后每次的最大值减去最小值,如果大于k,那么就更新两个中的一个,应该更新位置较小的那个,这样才能使得这个区间的长度最大,然后就这么更新就行了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int a[maxn], Q1[maxn], Q2[maxn];
int main()
{
int n, m, k;
while(scanf("%d%d%d", &n, &m, &k) != EOF)
{
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
int s1 = 0, e1 = 0, s2 = 0, e2 = 0, pos = 0, ans = 0;
for(int i = 1; i <= n; i++)
{
while(s1 < e1 && a[Q1[e1-1]] < a[i]) e1--;
while(s2 < e2 && a[Q2[e2-1]] > a[i]) e2--;
Q1[e1++] = i;
Q2[e2++] = i;
while(s1 < e1 && s2 < e2 && a[Q1[s1]] - a[Q2[s2]] > k)
{
if(Q1[s1] < Q2[s2])
pos = Q1[s1++];//注意这里是s1++不是++s1
else
pos = Q2[s2++];
}
if(a[Q1[s1]] - a[Q2[s2]] >= m)
ans = max(ans, i - pos);
}
printf("%d\n", ans);
}
return 0;
}