[luogu1168]中位数_优先队列
中位数
题目大意:输出读入的前2*k+1个数的中位数。一共有n个数,按照读入顺序。
注释:$1\le n \le 10^9$。
想法:这是优先队列的一个应用qwq。我们弄两个堆。小根堆和大根堆,保证:大根堆中的任意一个数都小于小根堆,而且大根堆中的元素个数始终比小根堆大且只大1。最后我们只需要输出大根堆的对顶即可。具体地:我们对于每一个新读入的元素和原本合法的大、小根堆进行操作,将当前元素和大根堆对顶进行比较,如果当前元素大于大根堆对顶,我们就将其扔进小根堆,反之,扔进大根堆,显然是正确的。在维护大、小根堆的数目时,我们通过循环处理,无非就是讲大、小根堆的堆顶倒来倒去。
最后,附上丑陋的代码... ...
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; priority_queue<int>q1; priority_queue<int,vector<int>,greater<int> >q2; // int a[100100]; int main() { int n; scanf("%d",&n); int sum_for_Big=0;//大根堆数目 int sum_for_Small=0;//小根堆数目 for(int i=1;i<=n;i++) { int a; scanf("%d",&a); if(i==1) { sum_for_Big=1; q1.push(a); sum_for_Small=0; printf("%d\n",a); } else { if(a<q1.top())//插入元素 { q1.push(a); sum_for_Big++; } else q2.push(a),sum_for_Small++; if(i%2==1) { while(sum_for_Big-sum_for_Small!=1)//维护大、小根堆的数目关系 { if(sum_for_Big<sum_for_Small) { int x=q2.top(); q2.pop(); sum_for_Small--; q1.push(x); sum_for_Big++; } else { int x=q1.top(); q1.pop(); sum_for_Big--; q2.push(x); sum_for_Small++; } } printf("%d\n",q1.top()); } } } // printf("%d %d\n",sum_for_Big,sum_for_Small); // printf("%d\n",q1.top()); // printf("%d\n",q2.top()); return 0; }/* 3 1 3 5 */
小结:priority的应用,好像suika学长说heap比这鬼东西快一万倍... ...
| 欢迎来原网站坐坐! >原文链接<