XKC , the captain of the basketball team , is directing a train of nn team members. He makes all members stand in a row , and numbers them 1 \cdots n1⋯n from left to right.
The ability of the ii-th person is w_iwi , and if there is a guy whose ability is not less than w_i+mwi+mstands on his right , he will become angry. It means that the jj-th person will make the ii-th person angry if j>ij>i and w_j \ge w_i+mwj≥wi+m.
We define the anger of the ii-th person as the number of people between him and the person , who makes him angry and the distance from him is the longest in those people. If there is no one who makes him angry , his anger is -1−1 .
Please calculate the anger of every team member .
Input
The first line contains two integers nn and m(2\leq n\leq 5*10^5, 0\leq m \leq 10^9)m(2≤n≤5∗105,0≤m≤109) .
The following line contain nn integers w_1..w_n(0\leq w_i \leq 10^9)w1..wn(0≤wi≤109) .
Output
A row of nn integers separated by spaces , representing the anger of every member .
樣例輸入
6 1
3 4 5 6 2 10
樣例輸出
4 3 2 1 0 -1
題意:n個數,一個m值,對於每一個數i都從右往左找到第一個大於a[i]+m的數(這個數必須在i的右邊),找到了輸出這兩個數中間相隔了幾個數,找不到輸出-1.
思路:維護每一個區間的最大值。每次查詢先找右區間,再找左區間。
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
using namespace std;
#define MAX 1e9+7
#define inf 0x3f3f3f
//const int mm=1010;
const int M=5e5+10;
typedef long long ll;
int tree[M*4];
int a[M*4];
void bulid(int node,int left,int right)
{
if(left == right)
{
tree[node]=a[left];
return ;
}
int mid=(left+right)/2;
bulid(node*2,left,mid);
bulid(node*2+1,mid+1,right);
tree[node]=max(tree[node*2],tree[node*2+1]);
}
int query(int node,int l,int r,int p)
{
if(l==r)
return l;
int mid=(l+r)/2;
if(tree[node*2+1]>=p)//先找右子樹
return query(node*2+1,mid+1,r,p);
else{//再找左子樹
if(tree[node*2]>=p)
return query(node*2,l,mid,p);
else
return -1;
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
memset(tree,0,sizeof(tree));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
bulid(1,1,n);
for(int i=1;i<=n;i++)
{
int ans=query(1,1,n,a[i]+m);
if(ans==-1)//沒找到
{
if(i==n)
printf("-1\n");
else
printf("-1 ");
}
else{
if(ans>i)//找到了,並且在該數的右邊
{
if(i==n)
printf("%d\n",ans-i-1);
else
printf("%d ",ans-i-1);
}
else{//找到了,但在該數的左邊
if(i==n)
printf("-1\n");
else
printf("-1 ");
}
}
}
return 0;
}