/**
HDU 3530 单调队列的应用
题意:
给定一段序列,求出最长的一段子序列使得该子序列中最大最小只差x满足m<=x<=k。
解题思路:
建立两个单调队列分别递增和递减维护(头尾删除,只有尾可插入)
Max - Min 为两个队列的队首之差while(Max-Min>K) 看哪个的队首元素比较前就移动谁的
最后求长度时,需要先记录上一次的被淘汰的最值位置last ,这样[last+1,i]即为满足条件的连续子序列了
i - last
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=100005;
int q_max[N],q_min[N];//递增,递减
int a[N],n,m,k;
int main()
{
while(~scanf("%d%d%d",&n,&m,&k))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int head_min=0,head_max=0,tail_min=0,tail_max=0;
int left1=0,left2=0;
int maxx=0;
for(int i=1;i<=n;i++)
{
while(head_min<tail_min&&a[q_min[tail_min-1]]<=a[i])
tail_min--;
while(head_max<tail_max&&a[q_max[tail_max-1]]>=a[i])
tail_max--;
q_max[tail_max++]=q_min[tail_min++]=i;
/* printf("***%d 递减、递增***\n",i);
for(int j=head_min;j<tail_min;j++)
printf("%d ",a[q_min[j]]);
printf("\n");
for(int j=head_max;j<tail_max;j++)
printf("%d ",a[q_max[j]]);
printf("\n");*/
while(a[q_min[head_min]]-a[q_max[head_max]]>k)
{
if(q_min[head_min]<q_max[head_max])
left1=q_min[head_min++];
else
left2=q_max[head_max++];
}
if(a[q_min[head_min]]-a[q_max[head_max]]>=m)
maxx=max(maxx,i-max(left1,left2));
}
printf("%d\n",maxx);
}
return 0;
}
/*
5 2 3
1 -1 2 -6 5
5 1 3
1 2 3 4 5
6 0 0
-1 0 2 1 125 -5
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int a[maxn], q1[maxn], q2[maxn];
int main()
{
int n, m, k;
while(cin>>n>>m>>k) {
for(int i = 0; i<n; i++) {
scanf("%d", &a[i]);
}
int st1 = 0, st2 = 0, ed1 = 0, ed2 = 0, ans = 0, now = 0;
for(int i = 0; i<n; i++) {
while(st1<ed1&&a[q1[ed1-1]]<a[i]) //q1维护一个单调递减的数列,这样队头元素是最大值, 第二个是第二大的值
ed1--;
while(st2<ed2&&a[q2[ed2-1]]>a[i]) //q2维护一个单调递增的数列, 队头是最小值。
ed2--;
q1[ed1++] = q2[ed2++] = i;
while(st1<ed1&&st2<ed2&&a[q1[st1]]-a[q2[st2]]>k) { //如果最大值-最小值大于k
if(q1[st1]<q2[st2]) {
now = q1[st1++]+1; //如果最大值在序列中的位置小于最小值
} else {
now = q2[st2++]+1;
}
}
if(st1<ed1&&st2<ed2&&a[q1[st1]]-a[q2[st2]]>=m) {
ans = max(ans, i-now+1); //只有最大值-最小值大于等于m的时候才更新ans
}
}
cout<<ans<<endl;
}
}