【对顶堆】 动态中位数
传送门
题意
\(p\)组数据,每组有一个长度为\(M\)的序列,依次读入一个序列中每一个值\(x_{i}\),当读取个数为奇数的时候输出中位数
数据范围
\(\begin{array}{l}1 \leq P \leq 1000 \\ 1 \leq M \leq 9999\end{array}\)
题意
建立两个堆,一个大根堆,一个小根堆,来维护整个序列升序,小根堆的元素个数个数多一个
插入过程:
-
每次如果小根堆的为空插入小根堆
-
如果当前插入的数小于小根堆堆顶部,插入大根堆
- 判断两个堆的个数是否合法,不合法调换,小根堆堆顶的即当前的中位数
输出时判断是否已经输出\(10\)个来输出空格
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first
#define se second
#define ll long long
#define pb push_back
#define close ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef double db;
const ll mod=1e9+7;
const int N=1e5+10;
ll powmod(ll a,ll b,ll p)
{
ll res=1;
a%=p;
while(b)
{
if(b&1) res=res*a%p;
a=a*a%p;
b>>=1;
}
return res;
}
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
int _,id,n,x;
void solve()
{
cin>>id>>n;
cout<<id<<' '<<(n+1)/2<<endl;
int p=0;
priority_queue<int,vector<int>,greater<int>>mi;
priority_queue<int>mx;
rep(i,1,n+1)
{
cin>>x;
mi.push(x);
if(mx.size() && mx.top()>mi.top())
{
int t=mi.top(),lt=mx.top();
mi.pop();mx.pop();
mi.push(lt);mx.push(t);
}
if(mi.size() > mx.size()+1)
{
mx.push(mi.top());
mi.pop();
}
if(i&1)
cout<<mi.top()<<(++p%10 == 0?'\n':' ');
}
if(p%10) cout<<endl;
}
int main()
{
close;
cin>>_;
while(_--) solve();
}

浙公网安备 33010602011771号