维护一个集合,插入与删除操作,每一步结束之后,输出中位数
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define LL long long const int maxn = 100010; #define ls T[x].l #define rs T[x].r #define lls T[ls].l #define lrs T[ls].r #define rls T[rs].l #define rrs T[rs].r struct SBT{ //左子树指针,右子树指针,大小,键值 int l,r,sz,key; void init(){ l=r=key=0; sz=1; } }T[maxn]; int root,tot; //根的位置以及节点个数 //左旋转处理 void l_rot(int &x){ int k=rs; rs=T[k].l; T[k].l=x; T[k].sz=T[x].sz; T[x].sz=T[ls].sz+T[rs].sz+1; x=k; } //右旋转处理 void r_rot(int &x){ int k=ls; ls=T[k].r; T[k].r=x; T[k].sz=T[x].sz; T[x].sz=T[ls].sz+T[rs].sz+1; x=k; } //调整处理 void maintain(int &x,bool flag){ if(flag){ //更新右子树 if(T[rrs].sz>T[ls].sz) l_rot(x); else if(T[rls].sz>T[ls].sz){ r_rot(rs); l_rot(x); } else return; } else{ //更新在左子树 if(T[lls].sz>T[rs].sz) r_rot(x); else if(T[lrs].sz>T[rs].sz){ l_rot(ls); r_rot(x); } else return; } //更新子树,然后再更新根,直到平衡为止 maintain(ls,false); maintain(rs,true); maintain(x,false); maintain(x,true); } //插入新节点 void insert(int &r,LL k){ if(r==0){ r=++tot; T[r].init(); T[r].key=k; } else{ T[r].sz++; if(k<T[r].key) insert(T[r].l,k); else insert(T[r].r,k); //插入后要调整,保证平衡 maintain(r,k>=T[r].key); } } //删除结点,利用的是前驱替换 int remove(int &r,int k){ int d_key; if(!r) return 0; T[r].sz--; //前者说明就是要删的节点,后两者说明不存在此节点 if(T[r].key==k||(T[r].l==0&&k<T[r].key)||(T[r].r==0&&k>T[r].key)){ d_key=T[r].key; if(T[r].l&&T[r].r) T[r].key=remove(T[r].l,k+1); else r=T[r].l+T[r].r; return d_key; } else return remove(k<T[r].key?T[r].l:T[r].r,k); } int get_pre(int &x,int y,int k) { if(x == 0) return y; if(k > T[x].key) return get_pre(rs,x,k); else return get_pre(ls,y,k); } int get_next(int &x,int y,int k) { if(x == 0) return y; if(k < T[x].key) return get_next(ls,x,k); else return get_next(rs,y,k); } //取得第K大的数 int get_max_Kth(int &x,int k){ int t=T[rs].sz+1; if(t==k) return T[x].key; if(t<k) return get_max_Kth(ls,k-t); else return get_max_Kth(rs,k); } //取得第K小的数 int get_min_Kth(int &x,int k){ int t=T[ls].sz+1; if(t==k) return T[x].key; if(t<k) return get_min_Kth(rs,k-t); else return get_max_Kth(ls,k); } //查找树中是否存在元素 int find(int &r,LL k){ if(!r) return 0; if(T[r].key==k) return 1; if(k<T[r].key) return find(T[r].l,k); else return find(T[r].r,k); } //获得结点的名次 int get_rank(int &x,int k) { if(k<T[x].key) return get_rank(ls,k); else if(k>T[x].key) return get_rank(rs,k)+T[ls].sz+1; else return T[ls].sz+1; } //排序 void inorder(int &x) { if(x == 0) return; inorder(ls); printf("%d\n",T[x].key); inorder(rs); } int main(){ int t,q; scanf("%d",&t); while(t--){ scanf("%d",&q); tot=root=0; int cnt=0; int k; char str[10]; while(q--){ scanf("%s%d",str,&k); if(str[0]=='a'){ insert(root,k); cnt++; if(cnt&1) printf("%d\n",get_max_Kth(root,cnt/2+1)); else { LL ans=(LL)get_max_Kth(root,cnt/2)+(LL)get_max_Kth(root,cnt/2+1); if(ans&1)printf("%.1f\n",ans/2.0); else printf("%lld\n",ans/2); } } else{ if(!find(root,k)) {printf("Wrong!\n");continue;} cnt--; remove(root,k); if(cnt==0){printf("Empty!\n");continue;} if(cnt&1) printf("%d\n",get_max_Kth(root,cnt/2+1)); else { LL ans=(LL)get_max_Kth(root,cnt/2)+(LL)get_max_Kth(root,cnt/2+1); if(ans&1)printf("%.1f\n",ans/2.0); else printf("%lld\n",ans/2); } } } } return 0; }