【TYVJ1728】【洛谷P3369】—普通平衡树(FHQ_Treap)
原谅我一直以为这叫
不过这确实比旋转好写多了,还支持可持久化
主要就是和
看看代码就懂了
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res*f;
}
const int N=100006;
int siz[N],val[N],n,key[N],son[N][2];
#define lc(u) (son[u][0])
#define rc(u) (son[u][1])
int tot,rt=0,seed=233,mod=19260817;
inline int rnd(){
return seed=int(seed*482711ll%2147483647);
}
inline int addnode(int x){
siz[++tot]=1,val[tot]=x,key[tot]=rnd();
lc(tot)=rc(tot)=0;return tot;
}
inline int pushup(int u){
siz[u]=siz[lc(u)]+siz[rc(u)]+1;
}
inline void split(int u,int &a,int &b,int k){
if(u==0){
a=b=0;return;
}
if(val[u]<=k){
a=u,split(rc(u),rc(a),b,k);
}
else {
b=u,split(lc(u),a,lc(b),k);
}
pushup(u);
}
inline void merge(int &u,int a,int b){
if(!a||!b){
u=a+b;return;
}
if(key[a]<key[b])u=a,merge(rc(u),rc(a),b);
else u=b,merge(lc(u),a,lc(b));
pushup(u);
}
inline int find(int x,int k){
while(siz[lc(x)]+1!=k){
if(siz[lc(x)]>=k)
x=lc(x);
else k-=siz[lc(x)]+1,x=rc(x);
}
return x;
}
inline void insert(int k){
int r1=0,r2=0,u;
u=addnode(k);
split(rt,r1,r2,k);
merge(r1,r1,u);
merge(rt,r1,r2);
}
inline void delet(int x){
int r1=0,r2=0,r3=0;
split(rt,r1,r2,x);
split(r1,r1,r3,x-1);
merge(r3,lc(r3),rc(r3));
merge(r1,r1,r3);
merge(rt,r1,r2);
}
inline int getrk(int k){
int r1=0,r2=0;
split(rt,r1,r2,k-1);
int res=siz[r1]+1;
merge(rt,r1,r2);
return res;
}
inline int getval(int k){
return val[find(rt,k)];
}
inline int pre(int k){
int r1=0,r2=0;
split(rt,r1,r2,k-1);
int u=find(r1,siz[r1]);merge(rt,r1,r2);
return val[u];
}
inline int nxt(int k){
int r1=0,r2=0;
split(rt,r1,r2,k);
int u=find(r2,1);merge(rt,r1,r2);
return val[u];
}
int main(){
srand(time(NULL));
n=read();
for(int i=1;i<=n;i++){
int op=read(),x=read();
switch(op){
case 1:{
insert(x);
break;
}
case 2:{
delet(x);
break;
}
case 3:{
cout<<getrk(x)<<'\n';
break;
}
case 4:{
cout<<getval(x)<<'\n';
break;
}
case 5:{
cout<<pre(x)<<'\n';
break;
}
case 6:{
cout<<nxt(x)<<'\n';
break;
}
}
}
}