P3871 [TJOI2010]中位数

最近在学splay,一看要求中位数,就上一个单点修改splay吧 顺便安利一发splay写的极好(还行)的博客https://blog.csdn.net/zj_js_zxb/article/details/80258824

#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
inline int read(){
    int f=1,x=0;
    char c=getchar();
    while (c<'0'||c>'9'){if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return f*x;
}
const  int maxn=1e5+5;
int n,m,o,p,root,tot;
int s[maxn][2],f[maxn],v[maxn],w[maxn],c[maxn];
char ch[1006];
inline void up(int x){
    w[x]=w[s[x][0]]+w[s[x][1]]+c[x];
}
inline void rotate(int x){
    int y=f[x],z=f[y],k=s[y][1]==x;
    s[z][s[z][1]==y]=x;
    f[x]=z;
    s[y][k]=s[x][k^1];
    f[s[x][k^1]]=y;
    s[x][k^1]=y;
    f[y]=x;
    up(y);up(x);
}
void splay(int x,int g){
    while (f[x]!=g){
        int y=f[x],z=f[y];
        if (z!=g)
        (s[z][0]==y)^(s[y][0]==x)?rotate(x):rotate(y);
        rotate(x); 
    }
    if (g==0) root=x;
}
inline int search(int k){
    int u=root;
    while (1){
    int q=s[u][0];
    if (w[q]+c[u]<k)
    k-=w[q]+c[u],u=s[u][1];
    else if (w[q]>=k) u=q;
    else return v[u];   
    }
}
inline void insert(int x){
    int u=root,ff=0;
    while (u&&v[u]!=x) ff=u,u=s[u][x>v[u]];
    if (u) c[u]++;
    else {
        u=++tot;
        if (ff) s[ff][x>v[ff]]=u;
        s[u][0]=s[u][1]=0;
        f[tot]=ff;
        v[tot]=x;
        c[tot]=1;
        w[tot]=1;
    }
    splay(u,0);
}
int main(){
    n=read();
    tot=0;
    int r,cnt=0;
    insert(-2147483647);
    insert(+2147483647);
   for (int i=1;i<=n;i++) insert(read()),cnt++;
   n=read();
   for (int i=1;i<=n;i++){
     cin>>ch;
     if (ch[0]=='a')  cin>>r,insert(r),cnt++;
     else {

        int u=cnt/2+1;
        if (cnt%2==0) printf("%d\n",min(search(u),search(u+1)));
        else printf("%d\n",search(u+1));
        }
   }
    return  0;
}

猜你喜欢

转载自blog.csdn.net/Fatalzyc/article/details/80338386