1. 程式人生 > >luogu P3871 [TJOI2010]中位數

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; }