洛咕日报
普通平衡树
题解
#include<bits/stdc++.h>
using namespace std;
int son[1000010][2],val[1000010],cnt[1000010],Fa[1000010],size[1000010];
int root,ncnt;
int n,pd,num;
int Check(int x)
{
return son[Fa[x]][1]==x;
}
int pushup(int x)
{
size[x]=size[son[x][0]]+size[son[x][1]]+cnt[x];
}
int rotate(int x)
{
int y=Fa[x],z=Fa[y],chk=Check(x),tmp=son[x][!chk];
son[y][chk]=tmp;
Fa[tmp]=y;
son[z][Check(y)]=x;
Fa[x]=z;
son[x][!chk]=y;
Fa[y]=x;
pushup(x);
pushup(y);
}
int Splay(int x,int goal=0)
{
for(;Fa[x]!=goal;)
{
int y=Fa[x],z=Fa[y];
if(z!=goal)
{
if(Check(x)==Check(y))
{
rotate(y);
}
else
{
rotate(x);
}
}
rotate(x);
}
if(!goal)
{
root=x;
}
}
int Find(int x)
{
if(!root)
{
return 0;
}
int Res=root;
for(;son[Res][x>val[Res]]&&x!=val[Res];)
{
Res=son[Res][x>val[Res]];
}
Splay(Res);
}
int insert(int x)
{
int Res=root,p=0;
for(;Res&&val[Res]!=x;)
{
p=Res;
Res=son[Res][x>val[Res]];
}
if(Res)
{
cnt[Res]++;
}
else
{
Res=++ncnt;
if(p)
{
son[p][x>val[p]]=Res;
}
son[Res][0]=0;
son[Res][1]=0;
val[Res]=x;
Fa[Res]=p;
cnt[Res]=1;
size[Res]=1;
}
Splay(Res);
}
int xth(int x)
{
int Res=root;
for(;;)
{
if(x<=size[son[Res][0]]&&son[Res][0])
{
Res=son[Res][0];
}
else
{
if(x>size[son[Res][0]]+cnt[Res])
{
x-=size[son[Res][0]]+cnt[Res];
Res=son[Res][1];
}
else
{
return Res;
}
}
}
}
int RANK(int x)
{
Find(x);
return size[son[root][0]];
}
int Pre(int x)
{
Find(x);
if(val[root]<x)
{
return root;
}
int Res=son[root][0];
for(;son[Res][1];)
{
Res=son[Res][1];
}
return Res;
}
int Suc(int x)
{
Find(x);
if(val[root]>x)
{
return root;
}
int Res=son[root][1];
for(;son[Res][0];)
{
Res=son[Res][0];
}
return Res;
}
int Delete(int x)
{
int las=Pre(x),nex=Suc(x);
Splay(las);
Splay(nex,las);
int DEL=son[nex][0];
if(cnt[DEL]>1)
{
cnt[DEL]--;
Splay(DEL);
}
else
{
son[nex][0]=0;
}
}
int main()
{
cin>>n;
insert(-1000000000);
insert(1000000000);
for(int i=1;i<=n;i++)
{
cin>>pd>>num;
if(pd==1)
{
insert(num);
}
if(pd==2)
{
Delete(num);
}
if(pd==3)
{
cout<<RANK(num)<<endl;
}
if(pd==4)
{
cout<<val[xth(num+1)]<<endl;
}
if(pd==5)
{
cout<<val[Pre(num)]<<endl;
}
if(pd==6)
{
cout<<val[Suc(num)]<<endl;
}
}
}
文艺平衡树
题解
#include<bits/stdc++.h>
using namespace std;
int son[1000010][2],val[1000010],cnt[1000010],Fa[1000010],size[1000010],rev[1000010];
int root,ncnt;
int n,m,pd,num;
int Check(int x)
{
return son[Fa[x]][1]==x;
}
void pushup(int x)
{
size[x]=size[son[x][0]]+size[son[x][1]]+cnt[x];
}
void pushdown(int x)
{
if(rev[x])
{
swap(son[x][0],son[x][1]);
rev[son[x][0]]=!rev[son[x][0]];
rev[son[x][1]]=!rev[son[x][1]];
rev[x]=0;
}
}
void rotate(int x)
{
int y=Fa[x],z=Fa[y],chk=Check(x),tmp=son[x][!chk];
son[y][chk]=tmp;
Fa[tmp]=y;
son[z][Check(y)]=x;
Fa[x]=z;
son[x][!chk]=y;
Fa[y]=x;
pushup(y);
pushup(x);
}
void Splay(int x,int goal=0)
{
for(;Fa[x]!=goal;)
{
int y=Fa[x],z=Fa[y];
if(z!=goal)
{
if(Check(x)==Check(y))
{
rotate(x);
}
else
{
rotate(y);
}
}
rotate(x);
}
if(!goal)
{
root=x;
}
}
void Find(int x)
{
if(!root)
{
return ;
}
int Res=root;
for(;son[Res][x>val[Res]]&&x!=val[Res];)
{
Res=son[Res][x>val[Res]];
}
Splay(Res);
}
void insert(int x)
{
int Res=root,p=0;
for(;Res&&val[Res]!=x;)
{
p=Res;
Res=son[Res][x>val[Res]];
}
if(Res)
{
cnt[Res]++;
}
else
{
Res=++ncnt;
if(p)
{
son[p][x>val[p]]=Res;
}
son[Res][0]=0;
son[Res][1]=0;
val[Res]=x;
Fa[Res]=p;
cnt[Res]=1;
size[Res]=1;
}
Splay(Res);
}
int xth(int x)
{
int Res=root;
for(;;)
{
pushdown(Res);
if(x<=size[son[Res][0]]&&son[Res][0])
{
Res=son[Res][0];
}
else
{
if(x>size[son[Res][0]]+cnt[Res])
{
x-=size[son[Res][0]]+cnt[Res];
Res=son[Res][1];
}
else
{
return Res;
}
}
}
}
void REV(int L,int R)
{
int x=xth(L),y=xth(R+2);
Splay(x);
Splay(y,x);
rev[son[y][0]]=!rev[son[y][0]];
}
int RANK(int x)
{
Find(x);
return size[son[root][0]];
}
int Pre(int x)
{
Find(x);
if(val[root]<x)
{
return root;
}
int Res=son[root][0];
for(;son[Res][1];)
{
Res=son[Res][1];
}
return Res;
}
int Suc(int x)
{
Find(x);
if(val[root]>x)
{
return root;
}
int Res=son[root][1];
for(;son[Res][0];)
{
Res=son[Res][0];
}
return Res;
}
void Delete(int x)
{
int las=Pre(x),nex=Suc(x);
Splay(las);
Splay(nex,las);
int DEL=son[nex][0];
if(cnt[DEL]>1)
{
cnt[DEL]--;
Splay(DEL);
}
else
{
son[nex][0]=0;
}
}
void output(int x)
{
pushdown(x);
if (son[x][0])
output(son[x][0]);
if(val[x]&&val[x]<=n)
printf("%d ", val[x]);
if(son[x][1])
output(son[x][1]);
}
int main()
{
cin>>n>>m;
for(int i=0;i<=n+1;i++)
{
insert(i);
}
int ipl,ipr;
for(int i=1;i<=m;i++)
{
cin>>ipl>>ipr;
REV(ipl,ipr);
}
output(root);
}
简单点的平衡树(要long long)
#include<bits/stdc++.h>
using namespace std;
long long n,q,pd,num;
long long val[1000010],fa[1000010],size[1000010],cnt[1000010],son[1000010][2];
long long root,ncnt;
int Check(long long x)
{
return son[fa[x]][1]==x;
}
void pushup(long long x)
{
size[x]=size[son[x][1]]+size[son[x][0]]+cnt[x];
}
void rotate(long long x)
{
long long y=fa[x],z=fa[y],chk=Check(x),tt=son[x][!chk];
son[y][chk]=tt;
fa[tt]=y;
son[z][Check(y)]=x;
fa[x]=z;
son[x][!chk]=y;
fa[y]=x;
pushup(y);
pushup(x);
}
void Splay(long long x,long long goal=0)
{
while(fa[x]!=goal)
{
long long y=fa[x],z=fa[y];
if(z!=goal)
{
if(Check(x)==Check(y))
{
rotate(y);
}
else
{
rotate(x);
}
}
rotate(x);
}
if(!goal)
{
root=x;
}
}
void Find(long long x)
{
if(!root)
return;
long long res=root;
for(;son[res][x>val[res]]&&x!=val[res];)
{
res=son[res][x>val[res]];
}
Splay(res);
}
void insert(long long x)
{
long long res=root,p=0;
for(;res&&x!=val[res];)
{
p=res;
res=son[res][x>val[res]];
}
if(res)
{
cnt[res]++;
}
else
{
res=++ncnt;
if(p)
{
son[p][x>val[p]]=res;
}
son[res][1]=0;
son[res][0]=0;
cnt[res]=1;
val[res]=x;
fa[res]=p;
size[res]=1;
}
Splay(res);
}
int xth(long long x)
{
long long res=root;
for(;;)
{
if(x<=size[son[res][1]]&&son[res][1])
{
res=son[res][1];
}
else
{
if(x>size[son[res][1]]+cnt[res])
{
x-=size[son[res][1]]+cnt[res];
res=son[res][0];
}
else
{
return res;
}
}
}
}
int main()
{
cin>>n>>q;
insert(-10000000000000);
insert(10000000000000);
long long iptmp;
for(int i=1;i<=n;i++)
{
cin>>iptmp;
insert(iptmp);
}
for(int i=1;i<=q;i++)
{
cin>>pd>>num;
if(pd==1)
{
cout<<val[xth(num+1)]<<endl;
}
if(pd==2)
{
insert(num);
}
}
}