XKC's basketball team【线段树查询】

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?+m stands 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

题目大意:1.给出一个长度为n的数列,给出m的值。问在数列中从右到左第一个比 arr[i] + m 大的值所在位置与 arr[i] 的所在位置之间夹着多少个数。解题思路:1.用线段树来记录区间最大值,优先从右子树开始查询是否存在大于 arr[i] + m的值,返回下标即该值在原数列中的位置,即可求得答案。2.重要的是查询的值必须是在 i 的右边,否则输出 -1代码如下:

 1 #include<stdio.h>
 2 #include<algorithm>
 3 using namespace std;
 4 const int MAXN = 5e5 + 10;
 5
 6 int n, m;
 7 int a[MAXN], ANS[MAXN];
 8
 9 struct Tree
10 {
11     int val, l, r;
12 }tree[4 * MAXN];
13
14 void build(int k, int l, int r)
15 {
16     tree[k].l = l, tree[k].r = r;
17     if(l == r)
18     {
19         tree[k].val = a[l];
20         return ;
21     }
22     int mid = (l + r) / 2;
23     build(2 * k, l, mid);
24     build(2 * k + 1, mid + 1, r);
25     tree[k].val = max(tree[2 * k].val, tree[2 * k + 1].val);
26 }
27
28 int query(int k, int goal)
29 {
30     if(tree[k].l == tree[k].r)
31         return tree[k].l;
32     if(tree[2 * k + 1].val >= goal)
33         return query(2 * k + 1, goal);
34     else if(tree[2 * k].val >= goal)
35         return query(2 * k, goal);
36     else
37         return -1;
38 }
39
40 int main()
41 {
42     scanf("%d%d", &n, &m);
43     for(int i = 1; i <= n; i ++)
44         scanf("%d", &a[i]);
45     build(1, 1, n); //线段树建树
46     for(int i = 1; i <= n; i ++)
47     {
48         int flag = 0;
49         int ans = query(1, a[i] + m); //由右边开始查询,返回右边第一个大于 a[i] + m值的位置
50         if(ans == -1 || ans <= i)
51             ANS[i] = -1;
52         else if(ans > i)
53             ANS[i] = ans - i - 1;
54     }
55     printf("%d", ANS[1]);
56     for(int i = 2; i <= n; i ++)
57         printf(" %d", ANS[i]);
58     printf("\n");
59     return 0;
60 }

XKC's basketball team【线段树查询】

原文地址:https://www.cnblogs.com/yuanweidao/p/11493458.html

时间: 2024-10-29 04:36:08

XKC's basketball team【线段树查询】的相关文章

2019徐州网络赛 XKC&#39;s basketball team 线段树

网址:https://nanti.jisuanke.com/t/41387 题意: 大家好,我是训练时长两年半的个人练习生蔡徐坤,我的爱好是唱,跳,rap,篮球. 给出一段长度为$n,(n \leq 1e5)$的序列,对每一个数,求出它和它后面比它大$m$的数中间夹着的数的数量,没有输出$-1$. 题解: 直接建线段树,维护最大值,然后查询时对第$i$个数,搜索区间$[i,n]$之中大于$num[i]+m$的值的位置的最大值,具体操作是先限定区间,然后求出所有合法位置,取最大值,如果搜索不到则返

PAT天梯赛练习题 L3-002. 堆栈(线段树查询第K大值)

L3-002. 堆栈 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 大家都知道“堆栈”是一种“先进后出”的线性结构,基本操作有“入栈”(将新元素插入栈顶)和“出栈”(将栈顶元素的值返回并从堆栈中将其删除).现请你实现一种特殊的堆栈,它多了一种操作叫“查中值”,即返回堆栈中所有元素的中值.对于N个元素,若N是偶数,则中值定义为第N/2个最小元:若N是奇数,则中值定义为第(N+1)/2个最小元. 输入格式: 输入第一行给出正整

【笔试】今日头条 - 线段树查询

[题目描述] 给定两个长度为 n 的整数数列 A 和 B.再给定 q 组查询,每次查询给出两个整数 x 和 y,求满足 Ai >= x 且 Bi >= y 这样的 i 的数量. 输入格式 第一行给定两个整数 n 和 q. 第二行给定数列 A,包含 n 个整数. 第三行给定数列 B,包含 n 个整数. 接下来 q 行,每行两个整数 x 和 y,意义如上所述. 输出格式 对于每组查询,输出所求的下标数量. 输入样例 3 2 3 2 4 6 5 8 1 1 4 8 输出样例 3 1 数据规模 对于 

hdu(3016) Man Down(线段树查询更新+dp)

这道题目可以说是游戏的简化版. 题目的大致意思是: 首先我们只有两种板,一种使能量增加,另一种却使能量减少. 最开始人物站在最高层,然后它一开始有100的生命值,它每次下落只能掉到离他最近的木板上去,当然他只能从左端点或者是右端点往下掉. 但是如果没有板满足如下情况的话,那么他就掉到最底下去了,如果此时他的能量小于等于0的话,那么他就会死亡,那么则输出-1:否则输出他所能获得能量的最大值. 现在的任务是叫你输出最大所能获得最大能量值. 思路: 1)我们要找到当前区间的分别从左右端点下去离他最近的

【线段树查询区间最值】poj 3264 Balanced Lineup

1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 const int maxn=50005; 6 struct Seg 7 { 8 int l,r,mi,ma; 9 }tree[maxn*4]; 10 int val[maxn]; 11 12 void build(int l,int r,int i=1) 13 { 14 tree[i].l=l; 15 tree[i].r=r; 16 if (l=

POJ P2828 Buy Ticket——线段树的其他信息维护

Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue… The Lunar New Year was approaching, but unluckily the Little Cat still had schedules going here and there. Now, he ha

ZOJ 3632 Watermelon Full of Water(dp+线段树或单调队列优化)

Watermelon Full of Water Time Limit: 3 Seconds      Memory Limit: 65536 KB Watermelon is very popular in the hot summer. Students in ZJU-ICPC Team also love watermelon very much and they hope that they can have watermelon to eat every day during the

HDOJ 5338 ZZX and Permutations 线段树+树状数组

[题意]: 给一个排列加上表示循环的括号,问如何让1到n的对应的字典序最大. 从1开始贪心每个数字可以往三个地方走,右边第一个,跳转到左边的某一个,和自己构成循环 对于走到右边第一个的情况,只要判断右边的那个有没有被占据就可以了,如果可以和右边的互换,那么需要在线段树中将右边的数置为0 跳转到左边的某一个,一个数如果跳转到左边的某一个则说明左边的那个是括号开头这个数是括号结尾,用一个线段树查询区间里的最大值,由于括号间是不能重叠的,所以需要用树状数组二分一下左边界.如果这个数是要跳转到左边的某个

HDU 4417 Super Mario (树状数组/线段树)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble agai