对顶堆时间复杂度(

P1168 中位数

Zlc晨鑫 @ 2021-08-03 16:08:29

所以对顶堆的时间复杂度是O(NlogN)吗?

怎么求出来的啊qwq

code:

#include <queue>
#include <cstdio>
#include <iostream>

using namespace std;

const int N = 1e5 + 10;

int a[N];
priority_queue<int> pq_max;
priority_queue<int, vector<int>, greater<int> > pq_min;

int main()
{
    int n, mid;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d", &a[i]);
        if (i & 1)
        {
            if (i == 1)
            {
                mid = a[i];
                printf("%d\n", a[1]);
            }
            else
            {
                int x = a[i - 1], y = a[i];
                if (x <= mid) pq_max.push(x);
                else pq_min.push(x);
                if (y <= mid) pq_max.push(y);
                else pq_min.push(y);
                // 更新中位数
                // 比中位数小(或等于)的数的个数小于比它大的数的个数
                while (pq_max.size() < pq_min.size())
                {
                    pq_max.push(mid);
                    mid = pq_min.top();
                    pq_min.pop();
                }
                // 反之亦然
                while (pq_max.size() > pq_min.size())
                {
                    pq_min.push(mid);
                    mid = pq_max.top();
                    pq_max.pop();
                }
                printf("%d\n", mid);
            }
        }
    }
    return 0;
}

by RuntimeErr @ 2021-08-03 16:18:08

每个元素最多只会进出堆一次,堆的操作是 logn,n 个元素就 O(nlogn)


by RuntimeErr @ 2021-08-03 16:18:35

仅仅是我的证明,好像是势能分析/kel


by Echidna @ 2021-08-03 16:27:01

每当你处理 2 个数,最多只有 4 次与堆有关的操作,于是进行与堆有关操作的次数为 \Theta(n) ,每次操作时间复杂度为 O(\log n) ,于是 总时间复杂度为 O(n\log n)


by Echidna @ 2021-08-03 16:27:16

@Zlc晨鑫


by Echidna @ 2021-08-03 16:30:21

啊,是 5 次,不过也只是常数


by Zlc晨鑫 @ 2021-08-03 16:32:15

@RuntimeErr @某学oi的蒟蒻

谢谢大佬们orz/kel


|