zoukankan      html  css  js  c++  java
  • 【待补】splay 模板

    #define _CRT_SECURE_NO_WARNINGS
    #include<cmath>
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<map>
    #include<string.h>
    using namespace std;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define ls(n) node[n].ch[0]
    #define rs(n) node[n].ch[1]
    const int N = 100010;
    const int INF = 0x3f3f3f3f;
    
    struct Splay {
        struct Node {
            int fa, ch[2];
            bool flip;
            int v, add, maxn, s;
            void init(int val)
            {
                v = maxn = val;
                s = 1;
                add = flip = ch[0] = ch[1] = 0;
            }
        }node[N];
        int root;
        //维护一个结点 
        void pushup(int n)
        {
            node[n].maxn = max(node[n].v, max(node[ls(n)].maxn, node[rs(n)].maxn));
            node[n].s = node[ls(n)].s + node[rs(n)].s + 1;
        }
        //标记向下传 
        void pushdown(int n)
        {
            if (n == 0) return;
            if (node[n].add) {
                if (ls(n)) {
                    node[ls(n)].v += node[n].add;
                    node[ls(n)].maxn += node[n].add;
                    node[ls(n)].add += node[n].add;
                }
                if (rs(n)) {
                    node[rs(n)].v += node[n].add;
                    node[rs(n)].maxn += node[n].add;
                    node[rs(n)].add += node[n].add;
                }
                node[n].add = 0;
            }
            if (node[n].flip) {
                if (ls(n)) node[ls(n)].flip ^= 1;
                if (rs(n)) node[rs(n)].flip ^= 1;
                swap(ls(n), rs(n));
                node[n].flip = 0;
            }
        }
        //旋转 
        void rotate(int n, int d)
        {
            int fn = node[n].fa;
            int ffn = node[fn].fa;
            node[fn].ch[d ^ 1] = node[n].ch[d];
            node[node[n].ch[d]].fa = fn;
    
            node[n].ch[d] = fn;
            node[fn].fa = n;
    
            node[ffn].ch[rs(ffn) == fn] = n;
            node[n].fa = ffn;
            pushup(fn);
        }
        //将结点n转到goal下 
        void splay(int n, int goal)
        {
            while (node[n].fa != goal)
            {
                int fn = node[n].fa;
                int ffn = node[fn].fa;
                pushdown(ffn), pushdown(fn), pushdown(n);
                bool d = (ls(fn) == n);
                bool d1 = (ls(ffn) == fn);
                if (ffn == goal) rotate(n, d);
                else
                {
                    if (d == d1) rotate(fn, d1); else rotate(n, d);
                    rotate(n, d1);
                }
            }
            pushup(n);
            if (goal == 0) root = n;
        }
        //找寻中序遍历中的第pos个结点 
        int select(int pos)
        {
            int u = root;
            pushdown(u);
            while (node[ls(u)].s != pos)
            {
                if (pos < node[ls(u)].s) u = ls(u);
                else
                {
                    pos -= node[ls(u)].s + 1;
                    u = rs(u);
                }
                pushdown(u);
            }
            return u;
        }
        //查询l~r最大值 
        int query(int l, int r)
        {
            int u = select(l - 1), v = select(r + 1);
            splay(u, 0); splay(v, u);
            return node[ls(v)].maxn;
        }
        //给l~r加上val 
        void update(int l, int r, int val)
        {
            int u = select(l - 1), v = select(r + 1);
            splay(u, 0); splay(v, u);
            node[ls(v)].v += val;
            node[ls(v)].maxn += val;
            node[ls(v)].add += val;
        }
        //翻转l~r 
        void reverse(int l, int r)
        {
            int u = select(l - 1), v = select(r + 1);
            splay(u, 0); splay(v, u);
            node[ls(v)].flip ^= 1;
        }
        //类似二分来建树,就是这段代码现在的我还不会用指针来替换 
        int build(int l, int r)
        {
            if (l > r) return 0;
            if (l == r) return l;
            int mid = (l + r) >> 1;
            int L, R;
            ls(mid) = L = build(l, mid - 1);
            rs(mid) = R = build(mid + 1, r);
            node[L].fa = node[R].fa = mid;
            pushup(mid);
            return mid;
        }
        //初始化 
        void init(int n)
        {
            node[0].init(-INF); node[0].s = 0;
            node[1].init(-INF);
            node[n + 2].init(-INF);
            for (int i = 2; i <= n + 2; i++)
                node[i].init(0);
            root = build(1, n + 2);
            node[root].fa = node[0].fa = 0;
            ls(0) = root;
        }
    }splay_tree;
    
    int main()
    {
        int n, m;
        scanf("%d%d", &n, &m);
        splay_tree.init(n);
        for (int i = 0; i < m; i++)
        {
            int opt, l, r, v;
            scanf("%d%d%d", &opt, &l, &r);
            if (opt == 1) { scanf("%d", &v); splay_tree.update(l, r, v); }
            if (opt == 2) splay_tree.reverse(l, r);
            if (opt == 3) printf("%d
    ", splay_tree.query(l, r));
        }
        return 0;
    }
    /*
    const int maxn = 55;
    const int inf = 1e9 + 5;
    ll n,m;
    struct splay_tree {
    struct node {
    int val, mx, add, sz, son[2];
    bool rev;
    void init(int _val) { val = mx = _val, sz = 1, add = rev = son[0] = son[1]; }
    }T[maxn];
    int fa[maxn], root;
    
    void Rotate(int x, int kind) {
    int y = fa[x], z = fa[y];
    T[y].son[!kind] = T[x].son[kind], fa[T[x].son[kind]] = y;
    T[x].son[kind] = y, fa[y] = x;
    T[z].son[T[z].son[1] == y] = x, fa[x] = z;//orz
    }
    void Splay(int x,)
    };
    string s[maxn];
    map<char, int> mmp;
    
    int main()
    {
    cin >> n >> m;
    hehe.init();
    for (int i = 0, a, b, c, d; i < m; i++) {
    scanf("%d", &a);
    if (a == 1) { scanf("%d%d%d", &b, &c, &d); hehe.update(b, c, d); }
    else if (a == 2) { scanf("%d%d", &b, &c); hehe.Reverse(b, c); }
    else { scanf("%d%d", &b, &c); printf("%d
    "); hehe.query(b, c); }
    }
    
    return 0;
    }*/
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    JavaSE 基础 第51节 定义自己的异常
    JavaSE 基础 第50节 Java中的异常链
    JavaSE 基础 第49节 手动抛出异常
    JavaSE 基础 第48节 Java中的异常声明
    JavaSE 基础 第47节 获取异常信息
    JavaSE 基础 第46节 异常的分类
    JavaSE 基础 第45节Java异常快速入门
    JavaSE 基础 第44节 引用外部类的对象
    JavaSE 基础 第43节 静态内部类
    通用爬虫
  • 原文地址:https://www.cnblogs.com/SuuT/p/9508423.html
Copyright © 2011-2022 走看看