[模板][splay]

splay

——!x^n+y^n=z^n


update:[更新size]

1 int update(int x){
2         if(x){
3             siz[x]=cnt[x];
4             if(ch[x][0]) siz[x]+=siz[ch[x][0]];
5             if(ch[x][1]) siz[x]+=siz[ch[x][1]];
6         }
7     }

get:[判断是否为右孩子]

1 int get(int x){return ch[fa[x]][1]==x;}

clear:[清除一个节点]

1 int clear(int x){ch[x][0]=ch[x][1]=fa[x]=cnt[x]=key[x]=siz[x]=0;}

rotate:[旋转]

1 void rotate(int x){
2         int f=fa[x],ff=fa[f],p=get(x);
3         ch[f][p]=ch[x][p^1],fa[ch[f][p]]=f;
4         fa[f]=x,ch[x][p^1]=f,fa[x]=ff;
5         if(ff) ch[ff][ch[ff][1]==f]=x;
6         update(f),update(x);
7     }

splay:[转到根]

1 void splay(int x){
2         for(int f;(f=fa[x]);rotate(x))
3             if(fa[f]) rotate(get(x)==get(f)?f:x);
4         root=x;
5     }

insert:[插入一个点]

 1 void insert(int v){
 2         if(!root){
 3             sz++;root=sz;
 4             ch[sz][0]=ch[sz][1]=fa[sz]=0;
 5             key[sz]=v;
 6             cnt[sz]=siz[sz]=1;
 7             return ;
 8         }
 9         int now=root,f=0;
10         while(true){
11             if(v==key[now]){
12                 cnt[now]++;splay(now);return ;
13             }
14             f=now;now=ch[f][v>key[f]];
15             if(!now){
16                 sz++;
17                 ch[sz][0]=ch[sz][1]=0;
18                 key[sz]=v;
19                 siz[sz]=cnt[sz]=1;
20                 ch[f][v>key[f]]=sz;
21                 fa[sz]=f;
22                 splay(sz);
23                 return ;
24             }
25         }
26     }

find:[查找元素v在序列中的排名]

 1 int find(int v){
 2         int now=root,ans=0;
 3         while(true){
 4             if(v<key[now])
 5                 now=ch[now][0];
 6             else{
 7                 ans+=siz[ch[now][0]];
 8                 if(v==key[now]){
 9                     splay(now);
10                     return (ans+1);
11                 }
12                 ans+=cnt[now];
13                 now=ch[now][1];
14             }
15         }
16     }

findx:[查找排名为x的点]

 1 int findx(int x){
 2         int now=root;
 3         while(true){
 4             if(x<=siz[ch[now][0]])
 5                 now=ch[now][0];
 6             else{
 7                 int temp=siz[ch[now][0]]+cnt[now];
 8                 if(x<=temp){return key[now];}
 9                 x-=temp;
10                 now=ch[now][1];
11             }
12         }
13     }

pre:[前驱]

1 int pre(){
2         int now=ch[root][0];
3         while(ch[now][1]) now=ch[now][1];
4         return now;
5     }

next:[后继]

1 int next(){
2         int now=ch[root][1];
3         while(ch[now][0]) now=ch[now][0];
4         return now;
5     }

del:[删除一个点]

 1 void del(int x){
 2         find(x);
 3         if(cnt[root]>1){cnt[root]--;return ;}
 4         if(!ch[root][0]&&!ch[root][1]){clear(root);root=0;return ;}
 5         int of=root;
 6         if(!ch[root][0]){root=ch[root][1],fa[root]=0,clear(of);return ;}
 7         if(!ch[root][1]){root=ch[root][0],fa[root]=0,clear(of);return ;}
 8         int l=pre();
 9         splay(l);
10         ch[root][1]=ch[of][1];
11         fa[ch[of][1]]=root;
12         clear(of);
13         update(root);
14     }

 

posted @ 2017-10-28 08:41  iNx  阅读(170)  评论(0编辑  收藏  举报