洛谷 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 }