题目
For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far.
动态维护中位数问题:依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数。
题解
将整个数列排序后插入一个链表,然后按照读入顺序倒着删除,每删除一个整数x后,中位数位置变化最多为1,那么就可以根据x和中位数的大小关系和链表中元素的个数分类讨论
代码
#include <cstdio>
#include <algorithm>
using namespace std;
int p,n,mid;
struct smc{
int val,no;
}a[10004];
int l[10004],r[10004],v[10004],f[10004];
int ans[10004];
bool comp(smc a,smc b){
if (a.val==b.val) return a.no<b.no;
else return a.val<b.val;
}
int main(){
scanf("%d",&p);
for (int dd=1;dd<=p;dd++){
scanf("%d%d",&mid,&n);
mid=(1+n)/2;
for (int i=1;i<=n;i++){
scanf("%d",&a[i].val);
a[i].no=i;
}
sort(a+1,a+n+1,comp);
for (int i=1;i<=n;i++){
l[i]=i-1;
r[i]=i+1;
v[i]=a[i].val;
f[a[i].no]=i;
}
r[0]=1;l[1]=100;l[0]=l[1];
printf("%d %d\n",dd,n/2+1);
for (int i=n;i>=1;i-=2){
ans[i]=a[mid].val;
int m1=v[l[mid]],m2=v[r[mid]];
int m0=v[f[i]];
if (f[i]<mid)
if (f[i-1]<=mid) mid=r[mid];
if (f[i]>mid)
if (f[i-1]>=mid) mid=l[mid];
if (f[i]==mid)
if (f[i-1]>mid) mid=l[mid];
else mid=r[mid];
r[l[f[i]]]=r[f[i]];
l[r[f[i]]]=l[f[i]];
r[l[f[i-1]]]=r[f[i-1]];
l[r[f[i-1]]]=l[f[i-1]];
}
int cd=0;
for (int i=1;i<=n;i+=2){
printf("%d ",ans[i]);
if (++cd>=10) printf("\n"),cd-=10;
}
printf("\n");
}
}