poj 3784 Running Median 二叉堆
2016-07-06 21:11
316 查看
传送门
题目大意:
依次添加 n 个数,要求第奇数次添加时,输出当前数列中的中位数。
分析:
维护一个大根堆一个小根堆,大的数插入小根堆,小的数插入大根堆,每次取大根堆堆顶就是中位数
代码如下:(第一次手写二叉堆,所以是抄的POPOQQQ的模板>o< >_<)
by >o< neighthorn
题目大意:
依次添加 n 个数,要求第奇数次添加时,输出当前数列中的中位数。
分析:
维护一个大根堆一个小根堆,大的数插入小根堆,小的数插入大根堆,每次取大根堆堆顶就是中位数
代码如下:(第一次手写二叉堆,所以是抄的POPOQQQ的模板>o< >_<)
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; const int maxn=5000+5; int p,a,m; struct small_root_heap{//小根堆 int heap[maxn],size; void insert(int x){ heap[++size]=x; int t=size; while(t>1&&heap[t]<heap[t>>1])//不断向上调整直到比父结点不优为止 swap(heap[t],heap[t>>1]),t>>=1; } void pop(){//弹顶 int t=2; heap[1]=heap[size],heap[size--]=0; while(t<=size){ if(heap[t]>heap[t+1]&&t<size) t++; if(heap[t]<heap[t>>1])//不断向上调整直到比父结点不优为止 swap(heap[t],heap[t>>1]),t<<=1; else break; } } }topheap,bottomheap,empty;//topheap是小根堆,bottomheap是大根堆 void add(int x){ if(x<=-bottomheap.heap[1]) bottomheap.insert(-x); else topheap.insert(x);//小的插入大根堆,大的插入小根堆 //插入,保证下堆的任意元素都小于等于上堆的任意元素 //注意一定要和下堆堆顶比较,因为第一次插入后元素一定在下堆,如果和上堆堆顶比较就会WA while(topheap.size>bottomheap.size) bottomheap.insert(-topheap.heap[1]),topheap.pop(); while(bottomheap.size>topheap.size+1) topheap.insert(-bottomheap.heap[1]),bottomheap.pop(); //维护上下堆平衡,保证两堆元素数相等或下堆元素数比上堆元素数多1 } signed main(void){ scanf("%d",&p); while(p--){ scanf("%d%d",&a,&m); topheap=bottomheap=empty; printf("%d %d\n",a,(m+1)>>1); for(int i=1,x;i<=m;i++){ scanf("%d",&x); add(x); if(i&1){ printf("%d%c",-bottomheap.heap[1],i==m?'\n':' '); if(i%20==19) printf("\n"); } } } return 0; }
by >o< neighthorn
相关文章推荐
- 基于MapReduce的手机上网流量统计分析
- python环境安装
- BZOJ 4518: [Sdoi2016]征途
- 提高项目24-删除数组元素
- CF355div2
- 新生练习2
- classLoader读取文件与文件流读取文件示例与注意事项
- java中重载Overriding与重写Overloading的区别
- 01_AssignmentOperator赋值运算符函数
- JZOJ 3441. 小喵喵的新家
- 《leetCode》:Combination Sum III
- 读《联盟》
- Ubuntu16.04下配置laravel
- 传统企业做互联网的困局
- Project Euler 19: Counting Sundays
- js中如何在各个操作中共享信息
- leetcode题解日练--2016.7.6
- [JZOJ4438] K小数查询(经典分块)
- 面试
- NetBeans Support Weblog