题目链接: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;
}


京公网安备 11010502036488号