题意:
给定一个序列,从每一个数后面比它大至少 (m) 的数中求出与它之间最大的距离。如果没有则为 (−1)。
题目链接:https://nanti.jisuanke.com/t/41387
分析:
从后向前维护一个递增的队列,从后往前遍历,若当前的数大于队尾就进队,否则从该队列中二分找最小的比自己大至少 (m) 的数(因为是从后向前维护,所以先找的一定最优),二者之间的距离即为答案。若当前数小于队尾,那这个数一定没有队尾的数优,因为它既比队尾的数靠前,又比它小。
时间复杂度:(O(nlogn))
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int w[N],q[N],ans[N],pos[N];
int main()
{
int n,m,cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
for(int i=n;i>=1;i--)
{
if(cnt>0)
{
int t=lower_bound(q+1,q+1+cnt,w[i]+m)-q;
if(t>cnt)
{
ans[i]=-1;
t=lower_bound(q+1,q+1+cnt,w[i])-q;//队列中维护递增
if(t>cnt)
{
q[++cnt]=w[i];
pos[cnt]=i;//记录在原数组中的位置
}
}
else
ans[i]=pos[t]-i-1;
}
else
{
ans[i]=-1;
q[++cnt]=w[i];
pos[cnt]=i;
}
}
for(int i=1;i<=n;i++)
printf("%d%c",ans[i],i==n?'
':' ');
return 0;
}