题目
动态求中位数
分析(离线)
这道题可以用链表做,倒着推,一个个从链表内删除,求中位数之前需要排序,当然需要标记每个数在链表出现的位置
链表代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 10007
struct rec{
int val,id;
bool operator<(const rec &x)const{
return val<x.val;
}
}a[mod];
int t,n,f[mod],l[mod],r[mod],ans[mod];
int in(){
int ans=0,f=1; char c=getchar();
while ((c<48||c>57)&&c!='-') c=getchar();
if (c=='-') f=-f,c=getchar();
while (c>47&&c<58) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void print(int ans){if (ans>9) print(ans/10); putchar(ans%10+48);}
int main(){
t=in();
while (t--){
int v=in(); n=in(); int k=n+1>>1;
print(v); putchar(' '); print(k);
putchar('\n'); int tv=0,mid=k;
for (int i=1;i<=n;i++) a[i].val=in(),a[i].id=i;
std::stable_sort(a+1,a+1+n); r[0]=1; l[n+1]=n;
for (int i=1;i<=n;i++) f[a[i].id]=i,l[i]=i-1,r[i]=i+1;//快排&&建链表
for (int i=n;;i-=2){
if (i&1) ans[++tv]=a[mid].val;//中位数
if (i==1) break;
if (f[i]>=mid&&f[i-1]>=mid) mid=l[mid];//中位数在左边
else if (f[i]<=mid&&f[i-1]<=mid) mid=r[mid];//中位数在右边
l[r[f[i]]]=l[f[i]]; r[l[f[i]]]=r[f[i]];
l[r[f[i-1]]]=l[f[i-1]]; r[l[f[i-1]]]=r[f[i-1]];//删除
}
for (int i=k;i>=1;i--){
if (ans[i]<0) putchar('-'),ans[i]=-ans[i];
if (ans[i]) print(ans[i]);
else putchar('0');
if ((k-i)%10==9||i==1) putchar('\n'); else putchar(' ');
}
}
return 0;
}
分析(在线)
也可以用对顶堆的方式,小根堆的堆顶就是中位数
优先队列代码
#include <cstdio>
#include <queue>
std::priority_queue<int>q1,q2;
int in(){
int ans=0,f=1; char c=getchar();
while ((c<48||c>57)&&c!='-') c=getchar();
if (c=='-') f=-f,c=getchar();
while (c>47&&c<58) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void print(int ans){if (ans>9) print(ans/10); putchar(ans%10+48);}
int main(){
int t=in();
while (t--){
int n=in(),tv=0; print(n); putchar(' ');
n=in(); int k=n+1>>1; print(k); putchar('\n');
while (q1.size()) q1.pop();//清空
while (q2.size()) q2.pop();
for (int i=1;i<=n;i++){
int x=in();
if (i&1) q1.push(-x); else q2.push(x);//q1取相反数可改成小根堆
while (q1.size()&&q2.size()&&-q1.top()<q2.top()){//修改堆顶
int x=-q1.top(); q1.pop();
q1.push(-q2.top());
q2.pop(); q2.push(x);
}
if (i&1) {
if (q1.top()>0) putchar('-'),print(q1.top());
else if (q1.top()<0) print(-q1.top());
else putchar('0');
if (i!=n&&i%20==19) putchar('\n'); else putchar(' ');
}
}
putchar('\n');
}
return 0;
}