题目链接:https://ac.nowcoder.com/acm/problem/50940
题解:
方法1:对于动态维护中位数,可以选择使用两个优先队列,一个大优先一个小优先,并且保证大小两个优先队列的size相差不超过1即可,中位数一定会在size较大的那个队列的top位置。实时更新中位数,比大于等于中位数的数丢进小优先队列,否则丢进大优先队列,然后维护两个队列的size不超过1即可,比较简单。

方法2:主席树静态查询第k大模板题,建树之后,对于每个符合的奇数段[1,x],x是奇数,查询区间[1,x]的第(x+1)/2大元素即可

由于方法2的代码是模板题,就不提供了方法2代码了。
下面是提供的是方法1代码:

#include <cctype>
#include <cfloat>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <istream>
#include <iterator>
#include <list>
#include <map>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define PI 3.1415926535898
using namespace std;
int main() {
    int t;
    cin>>t;
    while(t--) {
        int idx,n;
        cin>>idx>>n;
        cout<<idx<<" "<<(n+1)/2<<endl; 
        priority_queue<int,vector<int>,greater<int>> Min;
        priority_queue<int> Max;
        int Mid;
        vector<int> ans;
        for (int i=1; i<=n; i++) {
            int num;
            cin>>num;
            if (i==1) Mid=num;
            if (num>=Mid) Min.push(num);
            else Max.push(num);
            if ((int)Min.size()-(int)Max.size()>1) {
                num=Min.top();
                Min.pop();
                Max.push(num);
            } else if ((int)Max.size()-(int)Min.size()>1) {
                num=Max.top();
                Max.pop();
                Min.push(num);
            }
            if (i%2) {
                if ((int)Min.size()>(int)Max.size()) Mid=Min.top();
                else Mid=Max.top();
                ans.push_back(Mid);
            } 
        }
        for (int i=0; i<ans.size(); i++) {
            if (i) {
                if (i%10) cout<<" ";
                else cout<<endl;
            }
            cout<<ans[i];
        }
        cout<<endl;
    }
    return 0;
}