Splay模板
Posted milk-feng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Splay模板相关的知识,希望对你有一定的参考价值。
#include<iostream> #include<cstring> #include<cstdio> #define Reg register #define INF 0x7ffffff using namespace std; int size,n,root; struct Tree int ch[2],val,cnt,size,fat; tree[1000050]; int GetFat(int x) return tree[tree[x].fat].ch[1]==x; void Update(int x) tree[x].size=tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+tree[x].cnt; return; void Rotate(int x) int y=tree[x].fat; int z=tree[y].fat; int k=GetFat(x); //先定义k //x.rch-->y.lch tree[y].ch[GetFat(x)]=tree[x].ch[k^1]; tree[tree[y].ch[k]].fat=y; //x-->z tree[z].ch[GetFat(y)]=x; tree[x].fat=z; //y-->x tree[x].ch[k^1]=y; tree[y].fat=x; Update(y); Update(x); //注意顺序 return; void Splay(int x,int goal) while(tree[x].fat!=goal) int y=tree[x].fat,z=tree[y].fat; if(z!=goal) if(GetFat(y)==GetFat(x)) Rotate(y); else Rotate(x); Rotate(x); if(goal==0) root=x; return; void Find(int num) int k=root; while(tree[k].ch[num>tree[k].val]&&num!=tree[k].val) k=tree[k].ch[num>tree[k].val]; Splay(k,0); return; int GetPre(int num) Find(num); if(tree[root].val<num) return root; int k=tree[root].ch[0]; while(tree[k].ch[1]) k=tree[k].ch[1]; return k; int GetNext(int num) Find(num); if(tree[root].val>num) return root; int k=tree[root].ch[1]; while(tree[k].ch[0]) k=tree[k].ch[0]; return k; void Insert(int num) int k=root,p=0; //Get position while(k&&tree[k].val!=num) p=k; //father k=tree[k].ch[num>tree[k].val]; if(k) ++tree[k].cnt; else k=++size; if(p) tree[p].ch[num>tree[p].val]=k; //接上 tree[k].ch[0]=tree[k].ch[1]=0; tree[k].fat=p; tree[k].val=num; tree[k].cnt=tree[k].size=1; Splay(k,0); //update & 转到根 return; void Delete(int num) int last=GetPre(num),next=GetNext(num); Splay(last,0); Splay(next,root); //root‘s rch‘s lch =num & 没有儿子 int del=tree[next].ch[0]; if(tree[del].cnt>1) //直接减 --tree[del].cnt; Splay(del,0); else tree[next].ch[0]=0; return; int GetVal(int num) int k=root; while(1) if(tree[k].ch[0]&&num<=tree[tree[k].ch[0]].size) //在左儿子 k=tree[k].ch[0]; else if(num>tree[tree[k].ch[0]].size+tree[k].cnt) //在右儿子 num-=(tree[tree[k].ch[0]].size+tree[k].cnt); //注意顺序 k=tree[k].ch[1]; else return k; //在根节点 int GetRank(int num) Find(num); return tree[tree[root].ch[0]].size; //之前Insert了1个极小数 int main() scanf("%d",&n); Insert(INF); Insert(-INF); //为了减少时间 for(Reg int i=1,x,y;i<=n;++i) scanf("%d%d",&x,&y); if(x==1) Insert(y); else if(x==2) Delete(y); else if(x==3) printf("%d\n",GetRank(y)); else if(x==4) printf("%d\n",tree[GetVal(y+1)].val); //排除极小值 else if(x==5) printf("%d\n",tree[GetPre(y)].val); else printf("%d\n",tree[GetNext(y)].val); return 0;
以上是关于Splay模板的主要内容,如果未能解决你的问题,请参考以下文章