Topic link: https: //www.jisuanke.com/contest/3005/267806
By establishing the value of the weights wi segment tree is the last position maintain wi appear, for the i-th individual answer queries segment tree [wi + m, max] interval maximum position POS, so if pos-i-1 or less -1 is greater than or equal to wi + m do not exist after the i, i-th individual or the answer is pos-i-1. Since wi is too large so the need for discrete wi
#include<iostream> #include<cmath> #include<algorithm> using namespace std; #define ll long long #define ls l,mid,rt<<1 #define rs mid+1,r,rt<<1|1 #define maxn 1000010 int n,m,mx[maxn<<2]; ll w[maxn],x[maxn],li[maxn],ans[maxn]; void pushup(int rt) { mx[rt]=max(mx[rt<<1],mx[rt<<1|1]); } void update(int L,int c,int l,int r,int rt) { if(l==r) { mx[rt]=c; return ; } int mid=l+r>>1; if(L<=mid)update(L,c,ls); else update(L,c,rs); pushup(rt); } int query(int L,int R,int c,int l,int r,int rt) { if(L<=l&&R>=r) { return mx[rt]; } int mid=l+r>>1,ret=0; if(L<=mid)ret=max(ret,query(L,R,c,ls)); if(R>mid)ret=max(ret,query(L,R,c,rs)); return ret; } int main() { scanf("%d%d",&n,&m); int tot=0; for(int i=1;i<=n;i++) { scanf("%lld",&w[i]); x[++tot]=w[i]; x[++tot]=w[i]+m; } sort(x+1,x+1+tot); int nx=unique(x+1,x+1+tot)-x-1; int L; for(int i=1;i<=n;i++) { L=lower_bound(x+1,x+1+nx,w[i])-x; update(L,i,1,nx,1); } for(int i=1;i<=n;i++) { L=lower_bound(x+1,x+1+nx,w[i]+m)-x; L=query(L,nx,i,1,nx,1); if(L==-1)ans[i]=-1; else ans[i]=L-i-1; if(ans[i]<-1)ans[i]=-1; } for(int i=1;i<n;i++) printf("%lld ",ans[i]); printf("%lld\n",ans[n]); return 0; }