• [Note]Splay学习笔记


    开个坑记录一下学习Splay的历程。

    Code

    感谢rqy巨佬的代码,让我意识到了Splay可以有多短,以及我之前的Splay有多么的丑...

    int fa[N], ch[N][2], rev[N], sz[N], n;
    
    void upd(int x) { sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1; }
    void pd(int x) {
        if (rev[x]) {
            std::swap(ch[x][0], ch[x][1]);
            rev[ch[x][0]] ^= 1;
            rev[ch[x][1]] ^= 1;
            rev[x] = 0;
        }
    }
    int dir(int x) { return x == ch[fa[x]][1]; }
    void rot(int x) {
        int f = fa[x], d = dir(x);
        if (fa[x] = fa[f]) ch[fa[x]][dir(f)] = x;
        if (ch[f][d] = ch[x][d^1]) fa[ch[f][d]] = f;
        fa[ch[x][d^1] = f] = x;
        upd(f); upd(x);
    }
    int st[N];
    void splay(int x, int t = 0) {
        int top = 0;
        for (int i = x; fa[i]; i = fa[i]) st[top++] = fa[i];
        while (top--) pd(st[top]);
        pd(x);
        for (; fa[x] != t; rot(x)) if (fa[fa[x]] != t) rot(dir(fa[x]) == dir(x) ? fa[x] : x);
    }
    int kth(int k, int t) {
        int o = t;
        while (1) {
            pd(o); 
            if (sz[ch[o][0]] == k-1) break;
            else if (sz[ch[o][0]] >= k) o = ch[o][0];
            else { k -= sz[ch[o][0]]+1; o = ch[o][1]; }
        }
        splay(o, fa[t]);
        return o; 
    }
    void reverse(int l, int r) {
        splay(1);
        int y = kth(r+1, 1);
        int x = ch[y][0];
        kth(l-1, x);
        rev[ch[ch[y][0]][1]] ^= 1;
    }
    

    (以上是维护序列翻转的splay,码量1k多点,唯一的缺陷是压行太严重,不是很好调)

    Note

    一些小地方

    这个Splay的根是fa[i]=0的点,但是怎么找呢?不用管,直接splay(1),这样1就是根了啊(好暴力啊)。

    建树怎么建啊?也不用动脑子啊,直接建成一条链就行了啊,反正之后还要再调整,一开始建的那么完美没有用啊。

    关于标记

    一般维护序列问题,需要支持几种区间修改操作就打几个标记。
    不要忘了在splay前先pushdown所有祖先节点。

    区间翻转

    这个还是比较简单的,直接记录就行。

    区间加

    这个维护起来也不是很难,就是要注意标记下放的时候对维护的值的处理。

    关于应该维护的值

    这一部分也是十分的坑啊,只能多做题找感觉了。

    区间最值

    要注意0号点的值,不要傻乎乎的取最值的时候让0号点影响到答案。
    要分开维护每个节点的值和其子树的最值,不要偷懒只存一个啊(我有一个下午都浪费在了这上面...)。

  • 相关阅读:
    使用ant部署web项目
    搭建ant环境
    Myeclipse8.5,9.0安装svn插件
    自定义任务扩展 ANT
    使用jmeter测试 webservice
    随机数猜1-9的数字
    线性表
    显示所有线性元素
    新学到的继承链
    计算圆
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/splay.html
Copyright © 2020-2023  润新知