• SPLAY 未完待咕


    Splay(还没完先咕着)

    变量定义:
    (n:节点个数~~~ch[x][2]~0代表x左儿子~1代表右儿子)

    (val[x]x存储的值~~cnt[x]代表x存储的重复权个数~~fa[x]x爸爸~~siz[x]x子树下权值数)

    操作:

    chk,查询节点父亲方向

    pushup,更新size数组值

    void pushup(int x){siz[x] = siz[ch[x][0]]+siz[ch[x][1]]+cnt[x]}
    
    旋转(rotate)

    最开始树是这样的

    img

    我们把2号点整到4号点位置,2的下面就有子树1,3,4,5

    一种优秀做法是把4->2改成4->3,6->4改成6->2,2->3改成2->4

    splay需要rotate保持平衡,核心操作,旋转后中序遍历和合法性保持不变

    void rotate(int x){
    	int y = fa[x],z = fa[y],k = chk(x),w = ch[x][k^1];
    	ch[y][k] = w,fa[w] = y;
    	ch[z][chk(y)] = x;fa[x] = z;
    	ch[x][k^1] = y;fa[y] = x;
    	pushup(y);pushup(x);
    }
    
    伸展(splay)

    将一个节点一路rotate到指定节点的儿子。如果该点,fa,grandfa节点三点一线,应该先转fa

    void splay(int x,int goal = 0){
    	while(fa[x] != goal){
    	int y =fa[x],z = fa[y];
    	if(z != goal){
    	if(chk(x) == chk(y)) rotate(y);
    	else rotate(x);
    	}
    	rotate(x);
      }
      if(!goal) root = x;
    }
    
    find操作
    void find(int x){
    	if(!root) return;
    	int cur = root;
    	while(ch[cur][x > val[cur]] && x != val[cur]){
    		cur = ch[cur][x > val[cur]];
    	}
    	splay(cur);
    }
    
    insert插入

    从根节点开始,一路搜索下去。如果节点存在则直接自增cnt的值。否则新建节点并与父节点连边。因为新建节点时可能会拉出一条链,所以新建节点后需要将该节点splay到根节点。沿途的rotate操作可以使平衡树恢复平衡。

    void insert(int x){
    	int cur = root,p = 0;
        while(cur && val[vur] != x){
        
        }
    }
    
  • 相关阅读:
    找回消失的ubuntu启动选项
    搜索引擎的查询意图识别(关联分析)
    使用Eric构建Caffe应用程序-Baby年龄识别
    使用Caffe预测遇到的问题
    Caffe: Caffe的Python接口
    工厂模式-CaffeNet训练
    caffe特征提取/C++数据格式转换
    Vs2010无法打开文件“Kernel32.lib”、无法打开“libcpmt.lib”"msvcprt.lib"
    编译OpenCV遇到Qmake问题
    caffe学习笔记--跑个SampleCode
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13372315.html
Copyright © 2020-2023  润新知