P1168 题解

P1168 中位数 - 洛谷

很巧妙的一个题,自己没想出来。

用一个「对顶堆」来维护,即一个大根堆和一个小根堆。保证大根堆的队首 \(\le\) 小根堆的队首,并使他们的堆中元素的个数尽量相等。

操作如下:

  1. 每次加入一个元素时,如果这个数比大根堆的队首大,就加入小根堆;否则加入大根堆。
  2. 比较两个堆中的元素个数。如果差值 \(> 1\),将元素个数多的那堆的队首弹出,并加入到个数少的那堆,直到元素个数差值 \(\le 1\)
  3. 如果两堆的元素个数的差值为 \(1\),输出元素个数多的那堆的队首即可。
#include <iostream>  
#include <cstdio>  
#include <queue>  
using namespace std;  
  
const int N = 100010;  
int n, a[N];  
priority_queue<int> q1;  
priority_queue<int, vector<int>, greater<int> >q2;  
  
int main() {  
    scanf("%d", &n);  
  
    for (int i = 1; i <= n; i++) {  
        int t; scanf("%d", &t);  
//        printf("%d\n", t);  
        if (q1.empty()) q1.push(t);  
        else if (q1.top() >= t) q1.push(t);  
        else q2.push(t);  
        while (int(q1.size() - q2.size()) > 1) {  
            int tmp = q1.top();  
            q1.pop();  
            q2.push(tmp);  
        }  
        while (int(q2.size() - q1.size()) > 1) {  
            int tmp = q2.top();  
            q2.pop();  
            q1.push(tmp);  
        }  
        if (q2.size() > q1.size()) printf("%d\n", q2.top());  
        else if (q1.size() > q2.size()) printf("%d\n", q1.top());  
    }  
    return 0;  
}

调了大概 25min,因为 q1.size() - q2.size() 有精度问题。(我服了这都能出 bug)

posted @ 2024-04-22 14:10  White_Way  阅读(57)  评论(0)    收藏  举报