洛谷——P3871 [TJOI2010]中位数

 

P3871 [TJOI2010]中位数

 

一眼秒掉,这不是splay水题吗,套模板

#include<bits/stdc++.h>

#define IL inline
#define N 150005
using namespace std;

int ch[N][2],siz[N],val[N],cnt[N],f[N],root,ncnt;

IL void pushup(int k) {
    siz[k]=siz[ch[k][0]]+siz[ch[k][1]]+cnt[k];
}

IL int chk(int x) {
    return ch[f[x]][1]==x;
}

IL void rotate(int x) {
    int y=f[x],z=f[y],k=chk(x),w=ch[x][k^1];
    ch[y][k]=w,f[w]=y;
    ch[z][chk(y)]=x,f[x]=z;
    ch[x][k^1]=y,f[y]=x;
    pushup(y),pushup(x);
}

IL void splay(int x,int goal=0) {
    while(f[x]!=goal) {
        int y=f[x],z=f[y];
        if(z!=goal) {
            if(chk(x)==chk(y)) rotate(y);
            else rotate(x);
        }
        rotate(x);    
    }
    if(!goal) root=x;
}

IL void insert(int x) {
    int cur=root,p=0;
    while(cur&&x!=val[cur]) {
        p=cur;
        cur=ch[cur][x>val[cur]];
    }
    if(cur) {
        cnt[cur]++;
    } else {
        cur=++ncnt;
        if(p) ch[p][x>val[p]]=ncnt;
        f[cur]=p,siz[cur]=cnt[cur]=1;
        ch[cur][0]=ch[cur][1]=0;
        val[cur]=x;
    }
    splay(cur);
}

IL int kth(int k)
{
    int cur=root;
    while(1){
        if(ch[cur][0]&&k<=siz[ch[cur][0]]){
            cur=ch[cur][0];
        }else if(k>siz[ch[cur][0]]+cnt[cur]){
            k-=siz[ch[cur][0]]+cnt[cur];
            cur=ch[cur][1];
        }else return cur;
    }
}

int n,m;

int main() {
    scanf("%d",&n);
    for(int x,i=1; i<=n; i++) {
        scanf("%d",&x);
        insert(x);
    }
    scanf("%d",&m);
    char opt[10];
    for(int x,i=1; i<=m; i++) {
        scanf("%s",opt);
        if(opt[0]=='a') scanf("%d",&x),insert(x),++n;
        else printf("%d\n",val[kth(n/2+(n%2))]);
    }
    
    return 0;
}

 

入门题

开两个堆维护,大根堆维护小的中的最大值,小根堆维护打的中的最小值

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>

#define IL inline
#define N 150005
using namespace std;

int n,m;

priority_queue<int,vector<int> >q_1;//大根堆维护小值
priority_queue<int,vector<int>,greater<int> >q_2;//小根堆维护大值


void cz() {
    while(1) {
        int a=q_1.size(),b=q_2.size();
        if(abs(a-b)<=1) break;
        if(q_1.size()>q_2.size()) q_2.push(q_1.top()),q_1.pop();
        else q_1.push(q_2.top()),q_2.pop();
    }
}

int main() {
    scanf("%d",&n);
    for(int x,i=1; i<=n; i++) {
        scanf("%d",&x);
        if(i==1) q_1.push(x);
        else {
            if(x>q_1.top()) q_2.push(x);
            else q_1.push(x);
            cz();
        }
    }
    scanf("%d",&m);
    char opt[10];
    for(int x,i=1; i<=m; i++) {
        scanf("%s",opt);
        if(opt[0]=='a'){
            scanf("%d",&x);
            if(x>q_1.top()) q_2.push(x);
            else q_1.push(x);
            cz();
        }
        else {
            if(q_1.size()!=q_2.size()) q_1.size()>q_2.size()?printf("%d\n",q_1.top()):printf("%d\n",q_2.top());
            else printf("%d\n",min(q_2.top(),q_1.top()));
        }
    }

    return 0;
}

 

posted @ 2018-10-16 21:47  清风我已逝  阅读(124)  评论(0编辑  收藏  举报