zoukankan      html  css  js  c++  java
  • [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号点影响到答案。
    要分开维护每个节点的值和其子树的最值,不要偷懒只存一个啊(我有一个下午都浪费在了这上面...)。

  • 相关阅读:
    浏览器 页面报错
    TP单字母函数
    TP系统常量、项目后台的搭建、模板中常量字符串替换
    ThinkPHP3.2的简单知识
    面向对象基本概念,关键字,类的组成,静态,三大特性,创建类和对象,设计模式
    layui(弹出层)
    头像文件上传 方法一:from表单 方法二:ajax
    上传文件
    流程增加,发起事件,流程显示,处理。
    分页,条件查找后再分页
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/splay.html
Copyright © 2011-2022 走看看