luogu P3871 [TJOI2010]中位数

luogu P3871 [TJOI2010]中位数
平衡树模板?
貌似是的
写个插入和左右旋以及查询Kth就可以了
std:

#include<bits/stdc++.h>
using namespace std;
const int N=2000000;
struct node{//结构体重建树
    int l;//左儿子
    int r;//右儿子
    int k;//权值
    int p;//优先级
    int c;//重复元素个数
    int s;//子节点个数 
    #define l(x) t[x].l
    #define r(x) t[x].r
    #define v(x) t[x].k
    #define p(x) t[x].p
    #define c(x) t[x].c
    #define s(x) t[x].s
}t[N];
int pool=0;
int root;
int n;
int data;
int v=0;
inline void upt(const int &k){//传递 
    s(k)=s(l(k))+s(r(k))+c(k);
}
inline void zig(int &k){//左旋 
    int y=l(k);
    l(k)=r(y);
    r(y)=k;
    s(y)=s(k);
    upt(k);
    k=y;
}
inline void zag(int &k){//右旋 
    int y=r(k);
    r(k)=l(y);
    l(y)=k;
    s(y)=s(k);
    upt(k);
    k=y;
}
inline void ins(int &k,const int &val){//插入节点 
    if(!k){//新建一个节点
        k=++pool; 
        v(k)=val;
        p(k)=rand();//赋值一个随机的优先级 
        c(k)=s(k)=1;
        l(k)=r(k)=0;//没有左右儿子 
        return;
    }
    else ++s(k);
    if(v(k)==val) ++c(k);//有重复元素
    else if(val<v(k)){
        ins(l(k),val);
        if(p(l(k))<p(k)) zig(k);//左旋:维护堆性质 
    } 
    else{
        ins(r(k),val);
        if(p(r(k))<p(k)) zag(k);//右旋:维护堆性质 
    } 
}
int Rk(const int &val){
    int x=root;
    int res=0;
    while(x){
        if(val==v(x)) return res+s(l(x))+1;//找到了:返回排名 
        if(val<v(x)) x=l(x);
        else res+=s(l(x))+c(x),x=r(x); 
    }
}
inline int serch_min(const int &val){
    int x=root,res=-2147483647;
    while(x){
        if(v(x)<val) res=v(x),x=r(x);
        else x=l(x); 
    }
    return res;
}
inline int serch_max(const int &val){
    int x=root,res=-2147483647;
    while(x){
        if(v(x)>val) res=v(x),x=l(x);
        else x=r(x); 
    }
    return res; 
}
inline int Kth(int k){
    int x=root;
    while(x){
        if(s(l(x))<k&&s(l(x))+c(x)>=k) return v(x);
        if(s(l(x))>=k) x=l(x);
        else k-=s(l(x))+c(x),x=r(x);
    }
    return 0;
}
inline void del(int &k,const int &val){
    if(v(k)==val){
        if(c(k)>1) --c(k),--s(k);
        else if(!l(k)||!r(k)) k=l(k)+r(k);
        else if(p(l(k))<p(r(k))) zig(k),del(k,val);
        else zag(k),del(k,val);
        return;
    }
    --s(k);
    if(val<v(k)) del(l(k),val);
    else del(r(k),val);
    return;
} 
int main(){
    //freopen("a.out","w",stdout);
    int cnt=0;
    srand((unsigned)time(NULL));
    cin >> n;
    for(int i=1;i<=n;i++){
     scanf("%d",&data);
     ins(root,data);
 }
 v=n;
 int m;
 cin >> m;
    while(m--){
     char c;
     cin >> c;
        if(c=='a'){
         cin >> c >> c;
         scanf("%d",&data);
         ins(root,data);
         v++;
  }
  else{
   cin >> c >> c;
   int u=(v+1)/2;
   printf("%d\n",Kth(u));
  }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43872370/article/details/84887699