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 .
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) .
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
#include
#include
#include
#include
#include
#include
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;
}