http://pipioj.online/problem.php?id=1466
思路:利用堆可快速求出中位数(当然诸如
T
r
e
a
p
Treap
Treap之类的数据结构也是可以的),思路就是用大根堆维护最小的
(
n
+
1
)
/
2
(n+1)/2
(n+1)/2个元素,用小根堆维护最大的
n
/
2
n/2
n/2个元素,那么中位数要么等于大根堆堆顶要么等于两个堆顶之和再除
2
2
2。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
priority_queue<int,vector<int>,greater<int>> minq;
priority_queue<int,vector<int>,less<int>> maxq;
int n;
int main()
{
scanf("%d",&n);
int val,half;
double ans;
for(int i=1;i<=n;i++)
{
scanf("%d",&val);
maxq.push(val);
half=(i+1)>>1;
while(maxq.size()>half)
minq.push(maxq.top()),maxq.pop();
while(!minq.empty()&&maxq.top()>minq.top())
{
val=maxq.top();
maxq.pop();
maxq.push(minq.top());
minq.pop();
minq.push(val);
}
if(maxq.size()==minq.size())
ans=(maxq.top()+minq.top())/2.0;
else
ans=maxq.top();
printf("%.20f\n",ans);
}
return 0;
}
也可以根据元素的值进行更加细致的讨论:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
priority_queue<int,vector<int>,greater<int>> minq;
priority_queue<int,vector<int>,less<int>> maxq;
int n;
int main()
{
scanf("%d",&n);
int val;
double ans;
for(int i=1;i<=n;i++)
{
scanf("%d",&val);
if(maxq.empty())
maxq.push(val);
else if(maxq.size()>minq.size())
{
if(val<maxq.top())
{
minq.push(maxq.top());
maxq.pop();
maxq.push(val);
}
else
minq.push(val);
}
else
{
if(val<=minq.top())
maxq.push(val);
else
{
maxq.push(minq.top());
minq.pop();
minq.push(val);
}
}
if(maxq.size()==minq.size())
ans=(maxq.top()+minq.top())/2.0;
else
ans=maxq.top();
printf("%.20f\n",ans);
}
return 0;
}