• [模板][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     }

  • 相关阅读:
    win+ubuntu双系统安装后无法进入win7解决方法
    dell笔记本重装系统
    Linux下文件重命名、创建、删除、修改及保存文件
    个人网站
    如何给网页标题添加icon小图标
    CentOS 7最小化安装后找不到‘ifconfig’命令——修复小提示
    WIN10 通过Console连接交换机
    linux各文件夹的作用
    API设计指南(译)
    Petri网的工具
  • 原文地址:https://www.cnblogs.com/_inx/p/7745897.html
Copyright © 2020-2023  润新知