hdu3282 动态中位数(用堆实现)

来源:互联网 发布:golang channel 编辑:程序博客网 时间:2024/09/21 09:19

题意是求一个动态的中位数,用两个堆实现,一个是大根堆,一个是小根堆,且大根堆的元素个数等于小根堆的元素个数或者多一个,大根堆保存了比较小的前一半,小根堆保存了较大的后一半,每次求值的时候,取出大根堆的堆顶元素即可

#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<vector>#include<map>#include<queue>#include <iostream>using namespace std;const int N=1e5+10;int n,m;int a[N];struct heap{int a[N];int num;bool (*op)(int,int);void clear(){num=0;}void insert(int x){    a[++num]=x;    int t=num;    while(t>1 && op(a[t],a[t/2])){    swap(a[t],a[t/2]);    t/=2;    }}int getTop(){return a[1];}int getSize(){return num;}int pop(){int res=a[1];swap(a[1],a[num]);num--;int t=1;while(t*2<=num){int l=t*2;if(l<num && op(a[l+1],a[l])) l++;if(op(a[l],a[t])){swap(a[l],a[t]);t=l;}else break;}return res;}}h1,h2;bool max(int a,int b){return a>b;}bool min(int a,int b){return a<b;}int main() {    //freopen("aaa","r",stdin);int T;scanf("%d",&T);h1.op=max;    h2.op=min;while(T--){int id;scanf("%d",&id);scanf("%d",&n);printf("%d %d\n",id,(n+1)/2);int num=0;h1.clear();h2.clear();for(int i=1;i<=n;i++){scanf("%d",a+i);if(i&1){if(h1.getSize()==0 || a[i]<=h2.getTop()){h1.insert(a[i]);}else{h1.insert(h2.pop());h2.insert(a[i]);}num++;printf("%d%c",h1.getTop(),(num==10 || i==n)?'\n':' ');if(num==10) num=0;}else{if(a[i]<=h1.getTop()){h2.insert(h1.pop());h1.insert(a[i]);}else{h2.insert(a[i]);}}}}return 0;}


0 0
原创粉丝点击