Splay
我很开心,我终于大概搞明白Splay的写法了。归根到底还是因为我太弱了。
Splay和Treap差不多,都是通过一系列奇怪旋转保证树的平衡。但Splay的逻辑简单一点,把每次访问的节点旋转到树根,相当于是给树来了一次重组。写法上很奇怪,和我习惯有很大的出入,比如把zig和zag并到一起,以及用while代替递归操作,以及那个奇奇怪怪的Splay函数。理解了之后会稍微顺手一点。
献上极弱的代码,还是那道普通平衡树数据增强版,不知为何我这次一遍过甚至没有怎么调【滑稽】
#include<cstdio>
#define zczc
const int N=2000010;
const int maxn=0x7fffffff;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int min(int s1,int s2){
return s1<s2?s1:s2;
}
inline int max(int s1,int s2){
return s1<s2?s2:s1;
}
#define lc t[wh].ch[0]
#define rc t[wh].ch[1]
int root,cnt;
struct node{
int ch[2],f,data,num,sum;
}t[N];
inline void pushup(int x){
t[x].sum=t[t[x].ch[0]].sum+t[t[x].ch[1]].sum+t[x].num;
}
inline void rotate(int x){
int y=t[x].f;int z=t[y].f;int kk=x==t[y].ch[1];
t[z].ch[t[z].ch[1]==y]=x,t[x].f=z;
t[y].ch[kk]=t[x].ch[kk^1],t[t[x].ch[kk^1]].f=y;
t[x].ch[kk^1]=y,t[y].f=x;pushup(y);pushup(x);
}
inline void splay(int x,int rt){
while(t[x].f^rt){
int y=t[x].f;int z=t[y].f;
if(z^rt)(t[z].ch[1]==y)^(t[y].ch[1]==x)?rotate(x):rotate(y);
rotate(x);
}if(rt==0)root=x;
}
inline void insert(int val){
int ff=0,x=root;
while(x&&t[x].data!=val)ff=x,x=t[x].ch[val>t[x].data];
if(x)t[x].num++,t[x].sum++;
else t[ff].ch[val>t[ff].data]=x=++cnt,t[x].f=ff,t[x].data=val,t[x].num=t[x].sum=1;
splay(x,0);
}
inline int getmin(int wh,int val){
if(!wh)return maxn;
return t[wh].data<=val?getmin(rc,val):min(t[wh].data,getmin(lc,val));
}
inline int getmax(int wh,int val){
if(!wh)return -maxn;
return t[wh].data>=val?getmax(lc,val):max(t[wh].data,getmax(rc,val));
}
inline void find(int val){
int x=root;
while(t[x].data!=val&&t[x].ch[val>t[x].data])x=t[x].ch[val>t[x].data];
splay(x,0);return;
}
inline void join(int x,int y){
t[x].f=t[y].f=0;int rt=x;
while(t[x].ch[1])x=t[x].ch[1];
splay(x,0);t[x].ch[1]=y,t[y].f=root=x;
}
inline void del(int val){
find(val);if(t[root].num>1){t[root].num--,t[root].sum--;return;}
if(!t[root].ch[0]||!t[root].ch[1])t[root=t[root].ch[0]+t[root].ch[1]].f=0;
else join(t[root].ch[0],t[root].ch[1]);
}
inline int rank(int wh,int val){
if(!wh)return 0;
return t[wh].data<val?t[lc].sum+t[wh].num+rank(rc,val):rank(lc,val);
}
inline int get(int wh,int rk){
if(t[lc].sum<rk&&t[lc].sum+t[wh].num>=rk)return t[wh].data;
return t[lc].sum>=rk?get(lc,rk):get(rc,rk-t[lc].sum-t[wh].num);
}
#undef lc
#undef rc
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
int m,n,op,in,la=0,ans=0;
read(m);read(n);
for(int i=1;i<=m;i++){read(in);insert(in);}
while(n--){
read(op);read(in);in^=la;
switch(op){
case 1:
insert(in);break;
case 2:
del(in);break;
case 3:
ans^=(la=rank(root,in)+1);break;
case 4:
ans^=(la=get(root,in));break;
case 5:
ans^=(la=getmax(root,in));break;
case 6:
ans^=(la=getmin(root,in));break;
}
}
printf("%d",ans);
return 0;
}
一如既往,万事胜意
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具