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