使用对顶堆可解,左边的堆维护中位数前半部分,右边的堆维护中位数后半部分。在新的数进来的时候判断应该插左边还是右边,然后对左右如果差值超过1进行调整。
这样要么左堆的顶端是中位数,要么当左右相同大小的时候就是两个堆顶的数取平均数。
//对顶堆,以左边为承载多出来的那个中间数的堆
#include <bits/stdc++.h>

using namespace std;


int p;

int main() {
    
    cin>>p;
    while (p--) {
        priority_queue<int, vector<int>, less<int> > zuo;
        priority_queue<int, vector<int>, greater<int> > you;
        int num, m, val;
        cin>>num>>m;
        vector<int> v;
        for (int i=1;i<=m;i++) {
            cin>>val;
            if (zuo.size()==you.size()) {
                if (zuo.size()==0) {
                    zuo.push(val);
                } else if (you.top()<val) 
                {
                    you.push(val);
                    zuo.push(you.top());
                    you.pop();
                } else {
                    zuo.push(val);
                }
            }else {
                if (zuo.top()>=val) {
                    zuo.push(val);
                    you.push(zuo.top());
                    zuo.pop();
                } else {
                    you.push(val);
                }
            }
            if (i&1==1) {
                if (!zuo.empty()) {
                    if (zuo.size()==you.size()) v.push_back((zuo.top()+you.top())/2);
                    else v.push_back(zuo.top());
                }
            }
        }
        cout<<num<<" "<<v.size()<<endl;
        int i;
        for (i=0;i<v.size();i++) {
            cout<<v[i]<<" ";
            if ((i+1)%10==0) {
                cout<<endl;
            }
        }
        if (i%10!=0)
        cout<<endl;
    }
    
    
    return 0;
}