平衡树
记录下我的板子,题源 https://www.luogu.com.cn/problem/P3369
Splay
#include <bits/stdc++.h>
using namespace std;
const int inf=1e9;
int n,root,tot;
struct splay{
int ch[3],val,cnt;
int size,fa;
}a[1000010];
void Update(int p){
a[p].size=a[a[p].ch[0]].size+a[a[p].ch[1]].size+a[p].cnt;
}
void Rotate(int x){
int y=a[x].fa;
int z=a[y].fa;
int kid=a[y].ch[1]==x;
a[z].ch[a[z].ch[1]==y]=x;
a[x].fa=z;
a[y].ch[kid]=a[x].ch[kid^1];
a[a[x].ch[kid^1]].fa=y;
a[x].ch[kid^1]=y;
a[y].fa=x;
Update(y);
Update(x);
}
void Splay(int x,int goal){
while(a[x].fa!=goal){
int y=a[x].fa;
int z=a[y].fa;
if(z!=goal){
(a[z].ch[1]==y)^(a[y].ch[1]==x)?Rotate(x):Rotate(y);
}
Rotate(x);
}
if(goal==0){
root=x;
}
}
void Insert(int val){
int now=root,fa=0;
while(now&&a[now].val!=val){
fa=now;
now=a[now].ch[a[now].val<val];
}
if(now){
a[now].cnt++;
}
else{
now=++tot;
if(fa){
a[fa].ch[a[fa].val<val]=now;
a[now].fa=fa;
}
a[now].val=val;
a[now].size=a[now].cnt=1;
}
Splay(now,0);
}
void Search(int val){
int now=root;
if(!now){
return ;
}
while(a[now].val!=val&&a[now].ch[a[now].val<val]){
now=a[now].ch[a[now].val<val];
}
Splay(now,0);
}
int GetValByRank(int p,int rank){
if(!p){
return 0;
}
if(a[a[p].ch[0]].size>=rank){
return GetValByRank(a[p].ch[0],rank);
}
if(a[a[p].ch[0]].size+a[p].cnt>=rank){
return a[p].val;
}
return GetValByRank(a[p].ch[1],rank-a[a[p].ch[0]].size-a[p].cnt);
}
int GetPre(int val){
Search(val);
int pos=a[root].ch[0];
while(a[pos].ch[1]){
pos=a[pos].ch[1];
}
return pos;
}
int GetNext(int val){
Search(val);
int pos=a[root].ch[1];
while(a[pos].ch[0]){
pos=a[pos].ch[0];
}
return pos;
}
void Remove(int x){
int pre_x=GetPre(x);
int nxt_x=GetNext(x);
Splay(pre_x,0);
Splay(nxt_x,pre_x);
int pos=a[root].ch[1];
if(a[a[pos].ch[0]].cnt>1){
a[a[pos].ch[0]].cnt--;
Update(nxt_x);
Update(pre_x);
Splay(a[pos].ch[0],0);
return ;
}
a[pos].ch[0]=0;
Update(nxt_x);
Update(pre_x);
return ;
}
signed main(){
ios::sync_with_stdio(0);
cin>>n;
Insert(-inf);
Insert(inf);
for(int i=1;i<=n;i++){
int opt,x;
cin>>opt>>x;
if(opt==1){
Insert(x);
}
if(opt==2){
Remove(x);
}
if(opt==3){
Insert(x);
Search(x);
cout<<a[a[root].ch[0]].size<<endl;
Remove(x);
}
if(opt==4){
cout<<GetValByRank(root,x+1)<<endl;
}
if(opt==5){
Insert(x);
cout<<a[GetPre(x)].val<<endl;
Remove(x);
}
if(opt==6){
Insert(x);
cout<<a[GetNext(x)].val<<endl;
Remove(x);
}
}
}
Treap
#include <bits/stdc++.h>
using namespace std;
const int inf=0x7fffffff;
int n,tot,root;
struct Treap{
int l,r;
int dat,val;
int size,cnt;
}a[100010];
void Update(int p){
a[p].size=a[a[p].l].size+a[a[p].r].size+a[p].cnt;
}
int New(int val){
a[++tot].val=val;
a[tot].dat=rand();
a[tot].size=a[tot].cnt=1;
return tot;
}
void Build(){
New(-inf);
New(inf);
root=1;
a[1].r=2;
Update(root);
}
void zig(int &p){
int q=a[p].l;
a[p].l=a[q].r;
a[q].r=p;
p=q;
Update(a[p].r);
Update(p);
}
void zag(int &p){
int q=a[p].r;
a[p].r=a[q].l;
a[q].l=p;
p=q;
Update(a[p].l);
Update(p);
}
void Insert(int &p,int val){
if(p==0){
p=New(val);
return ;
}
if(a[p].val==val){
a[p].cnt++;
Update(p);
return ;
}
if(val<a[p].val){
Insert(a[p].l,val);
if(a[a[p].l].dat>a[p].dat){
zig(p);
}
}
else{
Insert(a[p].r,val);
if(a[a[p].r].dat>a[p].dat){
zag(p);
}
}
Update(p);
}
int GetRankByVal(int p,int val){
if(p==0){
return 0;
}
if(val==a[p].val){
return a[a[p].l].size+1;
}
if(val<a[p].val){
return GetRankByVal(a[p].l,val);
}
return GetRankByVal(a[p].r,val)
+a[a[p].l].size+a[p].cnt;
}
int GetValByRank(int p,int rank){
if(p==0){
return inf;
}
if(a[a[p].l].size>=rank){
return GetValByRank(a[p].l,rank);
}
if(a[a[p].l].size+a[p].cnt>=rank){
return a[p].val;
}
return GetValByRank(a[p].r,rank-a[a[p].l].size-a[p].cnt);
}
int GetPre(int val){
int ans=1;
int p=root;
while(p){
if(a[p].val==val){
if(a[p].l>0){
p=a[p].l;
while(a[p].r>0){
p=a[p].r;
}
ans=p;
}
break;
}
if(a[p].val>a[ans].val&&a[p].val<val){
ans=p;
}
p=val<a[p].val?a[p].l:a[p].r;
}
return a[ans].val;
}
int GetNext(int val){
int ans=2;
int p=root;
while(p){
if(a[p].val==val){
if(a[p].r>0){
p=a[p].r;
while(a[p].l>0){
p=a[p].l;
}
ans=p;
}
break;
}
if(a[p].val<a[ans].val&&a[p].val>val){
ans=p;
}
p=val<a[p].val?a[p].l:a[p].r;
}
return a[ans].val;
}
void Remove(int &p,int val){
if(p==0){
return ;
}
if(val==a[p].val){
if(a[p].cnt>1){
a[p].cnt--;
Update(p);
return ;
}
if(a[p].l||a[p].r){
if(a[p].r==0||a[a[p].l].dat>a[a[p].r].dat){
zig(p);
Remove(a[p].r,val);
}
else{
zag(p);
Remove(a[p].l,val);
}
Update(p);
}
else{
p=0;
return ;
}
}
val<a[p].val?Remove(a[p].l,val):Remove(a[p].r,val);
Update(p);
}
int main(){
ios::sync_with_stdio(0);
srand(0);
Build();
cin>>n;
for(int i=1;i<=n;i++){
int op,x;
cin>>op>>x;
if(op==1){
Insert(root,x);
}
if(op==2){
Remove(root,x);
}
if(op==3){
Insert(root,x);
cout<<GetRankByVal(root,x)-1<<endl;
Remove(root,x);
}
if(op==4){
cout<<GetValByRank(root,x+1)<<endl;
}
if(op==5){
cout<<GetPre(x)<<endl;
}
if(op==6){
cout<<GetNext(x)<<endl;
}
}
}

浙公网安备 33010602011771号