• 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 }
  • 相关阅读:
    IIT(ISM) Virtual Farewell E Dictator's plan for Valentine's day! 二分
    HDU
    LightOJ
    HDU 4407 Sum 容斥原理
    HDU 4686 Arc of Dream 矩阵快速幂
    uoj418
    Gym101237C The Palindrome Extraction Manacher
    Codeforces 100032 K
    codechef Suffix Palindromes
    Codeforces 932G Palindrome Partition
  • 原文地址:https://www.cnblogs.com/czc1999/p/11487024.html
Copyright © 2020-2023  润新知