题目描述
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.
题解
有两种方法第一种就是直接离散化后,用权值线段树查询第k大就行。这里主要说一下第二种,也就是对顶堆做法,
顾名思义,对顶的堆:一个最小值在前qq,一个最大值在前q,那么我们在不断插入数据的时候只要一直维护q最大值小于qq中最小值,并且q.size()==qq.size() OR q.size()==qq.size()+1即可
对顶堆代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define pb push_back
#define fi first
#define se second
#define ios ios::sync_with_stdio(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int maxn = 4e5 + 6;
const LL inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
LL qp(LL x,LL y){LL ans=1;x%=mod;while(y){if(y&1) ans=ans*x%mod;x=x*x%mod;y>>=1;}return ans;}
LL inv(LL x){return qp(x,mod-2);}
//head
int t,n,m,a[maxn],ans[maxn];
priority_queue<int>q;
priority_queue<int,vector<int>,greater<int> >qq;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
while(q.size()) q.pop();
while(qq.size()) qq.pop();
int cnt=0;
printf("%d %d\n",n,(m+1)/2);
for(int i=1;i<=m;i++){
if(i&1) q.push(a[i]);
else qq.push(a[i]);
if(i>=2){
if(q.top()>qq.top()){
int x=q.top(),y=qq.top();
q.pop();qq.pop();
q.push(y);qq.push(x);
}
}
if(i&1) ans[++cnt]=q.top();
}
for(int i=1;i<=cnt;i++){
printf("%d",ans[i]);
if(i%10==0) printf("\n");
else {
if(i==cnt) printf("\n");
else printf(" ");
}
}
}
}
权值线段树代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define pb push_back
#define fi first
#define se second
#define ios ios::sync_with_stdio(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int maxn = 4e5 + 6;
const LL inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
LL qp(LL x,LL y){LL ans=1;x%=mod;while(y){if(y&1) ans=ans*x%mod;x=x*x%mod;y>>=1;}return ans;}
LL inv(LL x){return qp(x,mod-2);}
//head
int t,n,m,a[maxn],b[maxn],ans[maxn];
int sum[maxn];
void update(int rt,int l,int r,int pos){
if(l==r) {sum[rt]++;return ; }
int mid=(l+r)>>1;
if(pos<=mid) update(rt<<1,l,mid,pos);
else update(rt<<1|1,mid+1,r,pos);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
int ask(int rt,int l,int r,int pos){
if(l==r){return l;}
int mid=(l+r)>>1,cnt=sum[rt<<1];
if(pos<=cnt) return ask(rt<<1,l,mid,pos);
else return ask(rt<<1|1,mid+1,r,pos-cnt);
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d",&a[i]),b[i]=a[i];
printf("%d %d\n",n,(m+1)/2);
sort(b+1,b+1+m);
n=unique(b+1,b+1+m)-b-1;
int c=0;
for(int i=1;i<=m;i++){
update(1,1,n,lower_bound(b+1,b+1+n,a[i])-b);
if(i&1){
ans[++c]=b[ask(1,1,n,(i+1)/2)];
}
}
for(int i=1;i<=c;i++){
printf("%d",ans[i]);
if(i%10==0) printf("\n");
else {
if(i==c) printf("\n");
else printf(" ");
}
}
for(int i=0;i<=4*n+10;i++) sum[i]=0;
}
}
京公网安备 11010502036488号