O(n) 取得数组中每个元素右边最后一个比它大的元素

题目

2019.9.7,icpc徐州网络赛的E题 XKC's basketball team ,计蒜客上还可以做。

链接:https://nanti.jisuanke.com/t/41387

Input

The first line contains two integers n and m ( 2 ≤ n ≤ 5∗10^5 ,0 ≤ m ≤ 10^9) .

The following  line contain n integers W1​..Wn​(0 ≤ Wi​ ≤ 10^9) .

Output

A row of n integers separated by spaces , representing the anger of every member .

样例输入

6 13 4 5 6 2 10

样例输出

4 3 2 1 0 -1

 

题意:

对于数组中的每个元素来说,如果它加上m之后,右边仍然有比它大的数(有多个的话,取距离最远的),这个距离就是我们要的结果,不存在取 -1。所以问题就是,取得数组中每个元素右边最后一个比它大的元素。

思路:

看了 “O(n) 取得数组中每个元素右边第一个比它大的元素” 的思路想到的。

  • 建立一个Node (value, index);value是原数组的值 + m,index是对应的索引。(具体的value是什么,视问题而定)
  • 建立壹 Node 的 value 值升序的优先级队列。也就是小根堆。
  •  i = n - 1,开始向前遍历

不断用当前堆顶的value值与arr[i]进行比较,如果堆顶元素小于arr[i],则找到需要找的元素。因为堆顶是最小的元素,如果堆顶大于arr[i],则i--,继续重复当前步骤。

  • 直到遍历完成,堆中大概率还会剩下几个(加+m之后,原数组中没有元素比它们大了),这些元素对应的 res 都是 -1 。
 1 #include <iostream>
 2 #include <queue>
 3 #include <stdio.h>
 4 using namespace std;
 5  
 6 int arr[500005];
 7 int anger[500005];
 8  
 9 struct Node {
10     int value, index;
11     Node(int v, int i) :value(v), index(i) {};
12     bool operator< (const Node& n)const {
13         return n.value < value;
14     }
15 };
16 priority_queue <Node>pq;
17  
18 int main() {
19     int n, m;
20     cin >> n >> m;
21     for (int i = 0; i < n; i++) {
22         scanf("%d", &arr[i]);
23         anger[i] = -1;
24         pq.push(Node(arr[i] + m, i));
25     }
26  
27     for (int i = n - 1; i >= 0; i--) {
28         while (!pq.empty()) {
29             int top = pq.top().value;
30             if (arr[i] >= top) {
31                 int index = pq.top().index;
32                 pq.pop();
33                 if (i > index) {
34                     anger[index] = i - index - 1;
35                 }
36                 else anger[index] = -1;
37             }
38             else break;
39         }
40     }
41  
42     for (int i = 0; i < n; i++) {
43         printf("%d", anger[i]);
44         if (i != n - 1)printf(" ");
45     }
46     
47     return 0;
48 }

 

posted @ 2019-09-08 16:21  czc1999  阅读(184)  评论(0编辑  收藏  举报