代码取材自BlackJack
Flag:我总有一天会把他辣眼睛的数组非递归式改成指针递归式!
bzoj 3224 普通平衡树
#include<bits/stdc++.h>
using namespace std;
const int N=100005,INF=1e9;
const double alpha=0.75;
struct sctree{int ch[2],fa,siz,val;}tree[N];
int root,tot;
void init(){
tot=2;root=1;
tree[1].val=-INF; tree[1].siz=2; tree[1].ch[1]=2;
tree[2].val=INF; tree[2].siz=1; tree[2].fa=1;
}
bool balance(int k){return (alpha*tree[k].siz>=1.0*tree[tree[k].ch[0]].siz)&&(alpha*tree[k].siz>=1.0*tree[tree[k].ch[1]].siz);}
int stac[N],top;
int build(int l,int r){
if(l>r) return 0;
int mid=l+r>>1,now=stac[mid];
tree[now].ch[0]=build(l,mid-1);
tree[now].ch[1]=build(mid+1,r);
tree[tree[now].ch[1]].fa=tree[tree[now].ch[0]].fa=now;
tree[now].siz=tree[tree[now].ch[0]].siz+tree[tree[now].ch[1]].siz+1;
return now;
}
void seek(int k){
if(!k) return;
seek(tree[k].ch[0]);
stac[++top]=k;
seek(tree[k].ch[1]);
}
void rebuild(int k){
top=0;seek(k);
int fa=tree[k].fa,son=(tree[fa].ch[1]==k),now=build(1,top);
tree[now].fa=fa;
tree[fa].ch[son]=now;
if(root==k) root=now;
}
void insert(int x){
int now=root,inv=0,i;
bool son;
tree[++tot].val=x;tree[tot].siz=1;
while(1){
++tree[now].siz;
son=(x>=tree[now].val);
if(tree[now].ch[son]) now=tree[now].ch[son];
else{
tree[tot].fa=now;
tree[now].ch[son]=tot;
break;
}
}
for(int i=tot;i;i=tree[i].fa) if(!balance(i)) inv=i;
if(inv) rebuild(inv);
}
inline int get_pos(int x){
int now=root;
while(tree[now].val!=x)
now=x<tree[now].val ? tree[now].ch[0] : tree[now].ch[1];
return now;
}
void del(int k){
if(tree[k].ch[0] && tree[k].ch[1]){
int goal=tree[k].ch[0];
while(tree[goal].ch[1]) goal=tree[goal].ch[1];
tree[k].val=tree[goal].val;
k=goal;
}
int tmp=tree[k].ch[0] ? tree[k].ch[0] : tree[k].ch[1], son=(tree[tree[k].fa].ch[1]==k);
tree[tree[k].fa].ch[son]=tmp; tree[tmp].fa=tree[k].fa;
if(root==k) root=tmp;
while(tree[k].fa) k=tree[k].fa,--tree[k].siz;
}
inline int Rank(int x){
int now=root,res=0;
while(now)
tree[now].val<x ? (res+=tree[tree[now].ch[0]].siz+1,now=tree[now].ch[1]) : now=tree[now].ch[0];
return res;
}
inline int Kth(int Kth){
int now=root;
while(1){
if(tree[tree[now].ch[0]].siz+1==Kth) return now;
tree[tree[now].ch[0]].siz>=Kth ? now=tree[now].ch[0] : (Kth-=tree[tree[now].ch[0]].siz+1,now=tree[now].ch[1]);
}
}
inline int Front(int x){
int now=root,res;
while(now) tree[now].val<x ? (res=tree[now].val,now=tree[now].ch[1]) : now=tree[now].ch[0];
return res;
}
inline int Back(int x){
int now=root,res;
while(now) tree[now].val>x ? (res=tree[now].val,now=tree[now].ch[0]) : now=tree[now].ch[1];
return res;
}
int main(){
int n,opt,x;
init();
scanf("%d",&n);
while(n--){
scanf("%d%d",&opt,&x);
switch(opt){
case 1: insert(x); break;
case 2: del(get_pos(x));break;
case 3: printf("%d\n",Rank(x));break;
case 4: printf("%d\n",tree[Kth(x+1)].val);break;
case 5: printf("%d\n",Front(x));break;
case 6: printf("%d\n",Back(x));break;
}
}
return 0;
}