//使用rmq办,ma[i][j],同i作为一个起点2^j阵列的最大长度值
//启动枚举问最长的子列
//枚举的最大长度2^(j-1)和2^(j)z之间
//然后在该范围内找到
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=100010;
int a[maxn],ma[maxn][25],mi[maxn][25];
int n,m,k;
void rmq()
{
for(int i=1;i<=n;i++)
ma[i][0]=mi[i][0]=a[i];
for(int j=1;j<=log((double)(n))/log(2.0);j++)
for(int i=1;i+(1<<j)-1<=n;i++)
{
ma[i][j]=max(ma[i][j-1],ma[i+(1<<(j-1))][j-1]);
mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);
}
}
int query(int a,int b)
{
int k=(int)(log((double)(b-a+1))/log(2.0));
return max(ma[a][k],ma[b-(1<<(k))+1][k])-min(mi[a][k],mi[b-(1<<(k))+1][k]);
}
int Maxlen(int st,int pos)
{
int j;
for(j=0;(pos+(1<<j))<=n;j++)
{
int tmp=query(st,pos+(1<<j));
if(tmp>k)
{
if(j==0)
return pos;
return Maxlen(st,pos+(1<<(j-1)));
}
}
if((pos+(1<<(j-1))==n))
return n;
else
return Maxlen(st,pos+(1<<(j-1)));
}
int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
rmq();
if(query(1,n)<m)
{
printf("0\n");
continue;
}
int ans=0;
for(int i=1;i<=n;i++)
{
int tmp=Maxlen(i,i-1);
ans=max(ans,tmp-i+1);
if(tmp==n||((n-i+1)<=ans))
break;
}
printf("%d\n",ans);
}
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。