luoguP3871 [TJOI2010]中位数

Posted sssy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP3871 [TJOI2010]中位数相关的知识,希望对你有一定的参考价值。

题目链接

luoguP3871 [TJOI2010]中位数

题解

平衡树

代码

#include<vector>    
#include<cstdio>    
#include<cstring>    
#include<algorithm>   
#define LL long long  
inline int read() {  
    int x = 0,f = 1;char c = getchar(); 
    while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}  
    while(c <= '9' &&c >= '0')x = x * 10 + c - '0',c = getchar(); 
    return x * f; 
} 
#define root ch[0][1]
const int maxn = 1000007; 
int n,a[maxn],Num = 0,val[maxn],fa[maxn],siz[maxn],ch[maxn][2],num[maxn]; 

inline int ident(int x) { return x == ch[fa[x]][0] ? 0 : 1;  } 

inline void connect(int x,int y,int which) {fa[x] = y,ch[fa[x]][which] = x;} 

inline void update(int x) { 
    siz[x] = siz[ch[x][1]] + siz[ch[x][0]] + num[x]; 
} 
void rotate(int x) { 
    int y = fa[x],z = fa[y]; 
    int yson = ident(x),zson = ident(y); 
    int ixson = ch[x][yson ^ 1]; 
    connect(ixson,y,yson); 
    connect(x,z,zson); 
    connect(y,x,yson ^ 1); 
    update(y); update(x); 
} 
void splay(int x,int to) {
    to = fa[to] ; 
    while(fa[x] != to) { 
        int y = fa[x]; 
        if(fa[y] == to) rotate(x); 
        else if(ident(x) == ident(y)) rotate(y),rotate(x); 
        else rotate(x),rotate(x); 
        //rotate(x); 
    } 
} 
int newnode(int Fa,int x) { 
    val[++ Num] = x; 
    fa[Num] = Fa;
    num[Num] = siz[Num] = 1; return Num; 
} 
void insert(int x) { 
    if(!root) {root = newnode(0,x);return ;} 
    int now = root; 
    while(now ) {
        siz[now] ++; 
        if(val[now] == x) {num[now] ++ ;return;} 
        int nxt = val[now] < x ? 1 : 0; 
        if(!ch[now][nxt] ){ch[now][nxt] = newnode(now,x); splay(ch[now][nxt],root);return;} 
        now = ch[now][nxt]; 
    } 
} 
int Arank(int x) { 
    int now = root; 
    while(now) { 
        int used = siz[now] - siz[ch[now][1]]; 
        if(x > siz[ch[now][0]] && x <= used) return val[now]; 
        if(used < x) x -= used,now = ch[now][1]; 
        else now = ch[now][0]; 
    }  
} 
int main() { 
    n = read(); 
    for(int i = 1;i <= n;++ i) insert(read()); 
    int q = read(); 
    char op[10]; 
    for(int i = 1;i <= q;++ i) { 
        scanf("%s",op + 1); 
        if(op[1] == 'a') { 
            insert(read()); n ++;   
        } else {
            printf("%d
",Arank(n / 2 + (n & 1)) );  
        }
    } 
    return 0; 
} 

以上是关于luoguP3871 [TJOI2010]中位数的主要内容,如果未能解决你的问题,请参考以下文章

TJOI2010中位数

[TJOI2010]中位数

luoguP3964 [TJOI2013]松鼠聚会

[LuoguP4094] [HEOI2016] [TJOI2016]字符串(二分答案+后缀数组+ST表+主席树)

[题解] LuoguP4091 [HEOI2016/TJOI2016]求和

省选刷题记录