[bzoj3224]普通平衡树
平衡树板子。因为懒得删点,这里直接num--,然后要注意查询前驱后继的时候不能直接输出只能(我只会)再查一遍Kth
写得丑别打我
- 代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct Splay{
int ch[2],fa;
int sum,num,sz;
}t[N];
int null=0,cnt,root;
inline bool son(int x){return t[t[x].fa].ch[1]==x;}
inline bool isroot(int x){return t[t[x].fa].ch[1]!=x&&t[t[x].fa].ch[0]!=x;}
inline int newnode(int _val){
cnt++;t[cnt].sum=_val,t[cnt].num++,t[cnt].sz=1;
return cnt;
}
inline void pushup(int x){
t[x].sz=t[x].num;
if(t[x].ch[1])t[x].sz+=t[t[x].ch[1]].sz;
if(t[x].ch[0])t[x].sz+=t[t[x].ch[0]].sz;
}
inline void rotate(int x){
int f=t[x].fa,gf=t[t[x].fa].fa;
bool a=son(x),b=son(x)^1;
if(!isroot(f))t[gf].ch[son(f)]=x;
t[x].fa=gf;
t[f].ch[a]=t[x].ch[b];t[t[x].ch[b]].fa=f;
t[x].ch[b]=f;t[f].fa=x;
pushup(f);pushup(x);//"pushup
}
inline void splay(int x){
while(!isroot(x)){
int f=t[x].fa;
if(!isroot(f)){
if(son(f)^son(x))rotate(x);
else rotate(f);
}
rotate(x);
}
root=x;
}
inline void ins(int v){
if(!root){root=newnode(v);return;}
int nw=root;
while(true){
t[nw].sz++;
if(t[nw].sum>v){
if(t[nw].ch[0])nw=t[nw].ch[0];
else {
t[nw].ch[0]=newnode(v);t[cnt].fa=nw;
nw=t[nw].ch[0];break;
}
}else if(t[nw].sum<v){
if(t[nw].ch[1])nw=t[nw].ch[1];
else {
t[nw].ch[1]=newnode(v);t[cnt].fa=nw;
nw=t[nw].ch[1];break;
}
}else if(t[nw].sum==v){t[nw].num++;break;}
}
splay(nw);
}
inline void del(int v){
int nw=root;
while(true){
t[nw].sz--;
if(t[nw].sum>v) nw=t[nw].ch[0];
else if(t[nw].sum<v) nw=t[nw].ch[1];
else if(t[nw].sum==v){t[nw].num--;break;}
}
splay(nw);
}
inline int Kth(int rk){
int nw=root;
while(true){
int l=t[t[nw].ch[0]].sz+1;
int r=l+t[nw].num-1;
if(rk<=r&&rk>=l)break;
else if(rk<=l-1) nw=t[nw].ch[0];
else if(rk>r){
rk-=r;nw=t[nw].ch[1];
}
}
splay(nw);
return t[nw].sum;
}
inline int PRE(int v){
int id=-1,nw=root;
while(true){
if(nw==null)break;
if(t[nw].sum<v){
id=nw;nw=t[nw].ch[1];
}
else nw=t[nw].ch[0];
}
splay(id);
return Kth(t[t[id].ch[0]].sz+t[id].num);
}
inline int AFT(int v){
int id=-1,nw=root;
while(true){
if(nw==null)break;
if(t[nw].sum>v){
id=nw;nw=t[nw].ch[0];
}
else nw=t[nw].ch[1];
}
splay(id);
return Kth(t[t[id].ch[0]].sz+1);
}
inline int ask(int v){
int nw=root;
while(true){
if(t[nw].sum==v) break;
else if(t[nw].sum<v) nw=t[nw].ch[1];
else if(t[nw].sum>v) nw=t[nw].ch[0];
}
splay(nw);
return t[t[nw].ch[0]].sz+1;
}
int T;
int main()
{
scanf("%d",&T);
while(T--){
int opt,x;
scanf("%d%d",&opt,&x);
if(opt==1) ins(x);
else if(opt==2) del(x);
else if(opt==3) printf("%d\n",ask(x));
else if(opt==4) printf("%d\n",Kth(x));
else if(opt==5) printf("%d\n",PRE(x));
else if(opt==6) printf("%d\n",AFT(x));
}
}