题解【洛谷P1801】黑匣子

题面

本题主要考察了对顶堆的用法。

首先保证整个序列是升序的,然后分别用一个大根堆和一个小根堆来维护 \(1\sim i-1\)\(i\sim n\) 的信息。

那么大根堆的堆顶就是 \(1\sim i-1\) 的最大值,小根堆的堆顶是 \(i\sim n\) 的最小值,也就是整个序列的第 \(i\) 小值。

每次输出也就要输出小根堆的堆顶。

在操作时需要维护堆的大小和两个堆顶之间的大小关系。

#include <bits/stdc++.h>

using namespace std;

const int N = 200003;

int n, m;
int a[N], b[N];
priority_queue <int> p; //大根堆
priority_queue <int, vector <int>, greater <int> > q; //小根堆

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i+=1) cin >> a[i];
    for (int i = 0; i < m; i+=1) cin >> b[i];
    sort(b, b + m);
    int i = 0, j = 0;
    while (i < n || j < m)
    {
        while (j < m && b[j] == i)
        {
            cout << q.top() << endl;
            p.push(q.top());
            q.pop();
            ++j;
        }
        int x = a[i];
        if (p.empty() || x >= q.top())
            q.push(x);
        else 
        {
            p.push(x);
            q.push(p.top());
            p.pop();
        }
        ++i;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xsl19/p/12639127.html