E:XKC's basketball team(The Preliminary Contest for ICPC Asia Xuzhou 2019)

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 
#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;
}

 

你可能感兴趣的:(组队赛,树)