分析:
线段树枚举 [ i , i + m ] [i,i+m] [i,i+m]区间中 m i n min min和 m a x max max 然后看它们的差是否 < = c <=c <=c即可
CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n,m,c,a[N],ok;
struct SegmentTree{
int l,r,maxn,minn;
}tree[N<<2];
void build(int x,int l,int r)
{
tree[x].l=l;tree[x].r=r;
if(l==r)
{
tree[x].maxn=tree[x].minn=a[l];
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
tree[x].maxn=max(tree[x<<1].maxn,tree[x<<1|1].maxn);
tree[x].minn=min(tree[x<<1].minn,tree[x<<1|1].minn);
}
int queryMax(int x,int L,int R)
{
if(L<=tree[x].l&&tree[x].r<=R)
return tree[x].maxn;
int mid=(tree[x].l+tree[x].r)>>1,res=-1;
if(L<=mid) res=max(res,queryMax(x<<1,L,R));
if(mid<R) res=max(res,queryMax(x<<1|1,L,R));
return res;
}
int queryMin(int x,int L,int R)
{
if(L<=tree[x].l&&tree[x].r<=R)
return tree[x].minn;
int mid=(tree[x].l+tree[x].r)>>1,res=0x7fffffff;
if(L<=mid) res=min(res,queryMin(x<<1,L,R));
if(mid<R) res=min(res,queryMin(x<<1|1,L,R));
return res;
}
int main()
{
scanf("%d%d%d",&n,&m,&c);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
for(int i=1;i+m-1<=n;i++)
{
int maxn=queryMax(1,i,i+m-1);
int minn=queryMin(1,i,i+m-1);
if(maxn-minn<=c)
{
printf("%d\n",i);
ok=1;
}
}
if(!ok) puts("NONE");
return 0;
}