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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章