寻找一个区间,满足:其中的最大值减最小值在[m,k]的范围内,输出最大的区间长度。
思路:维护2个单调队列,一个递增,一个递减。
用一个now记录现在的区间的起点,如果大的数-小的数比k还大,则可以丢弃小的那个区间,更新now。
最后的答案就是 max(ans,i-now);
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
inline int ReadInt()
{
char ch = getchar();
int data = 0;
while (ch < '0' || ch > '9')
{
ch = getchar();
}
do
{
data = data*10 + ch-'0';
ch = getchar();
}while (ch >= '0' && ch <= '9');
return data;
}
int n,sma,big;
inline bool isok(int x)
{
if(x>=sma&&x<=big) return true;
return false;
}
int a[100005];
int main()
{
while(scanf("%d%d%d",&n,&sma,&big)!=EOF)
{
deque<int> qs;
deque<int> qb;
int now=0,ans=0;
int flag=0;
int k;
for(int i=1;i<=n;i++)
{
a[i]=ReadInt();
}
for(int i=1;i<=n;i++)
{
while(!qs.empty()&&a[i]<=a[qs.back()]) qs.pop_back();
qs.push_back(i);
while(!qb.empty()&&a[i]>=a[qb.back()]) qb.pop_back();
qb.push_back(i);
while(!qb.empty()&&!qs.empty()&&a[qb.front()]-a[qs.front()]>big)
{
if(qb.front()>qs.front())
{
now=qs.front();
qs.pop_front();
}
else
{
now=qb.front();
qb.pop_front();
}
}
if(isok(a[qb.front()]-a[qs.front()]))
{
ans=max(ans,i-now);
}
}
printf("%d\n",ans);
}
return 0;
}