洛谷 P1801 黑匣子(优先队列)

传送门


解题思路

这一道题和中位数那道题很像,如果不会中位数请先看一下那道题——中位数

这道题和那道题不同的地方在于:

那道题的第一个大根堆队列的数字数量是数字总数的一半,是根据数学知识计算出来的,并且输出是每两个数输出一个;

这道题的第一个大根堆队列的数字数量是get(i)中的i,每用一次get函数i就会加一,而且输出是碰到get在指定位置输出。

——基本没怎么两样。

注意维护时不要忘记和小根堆或大根堆的堆顶进行比较,确定是把当前元素放在小根堆中还是放在大根堆中。

AC代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 using namespace std;
 5 const int maxn=200005;
 6 int m,n,g[maxn];
 7 long long a[maxn];
 8 priority_queue<long long> q1;
 9 priority_queue<long long,vector<long long>,greater<long long> > q2;
10 int main()
11 {
12     cin>>m>>n;
13     for(int i=1;i<=m;i++) scanf("%lld",&a[i]);
14     for(int i=1;i<=n;i++) scanf("%d",&g[i]);
15     int cnt=1;
16     for(int i=1;i<=n;i++){
17         for(;cnt<=g[i];cnt++){
18             if(q1.empty()||a[cnt]<=q1.top()) q1.push(a[cnt]);
19             else q2.push(a[cnt]);
20             if(q1.size()>i){
21                 q2.push(q1.top());
22                 q1.pop();
23             }
24         }
25         while(q1.size()<i){
26             q1.push(q2.top());
27             q2.pop();
28         }
29         printf("%lld\n",q1.top());
30     }
31     return 0;
32 }
posted @ 2019-12-26 21:11  尹昱钦  阅读(259)  评论(0编辑  收藏  举报