码迷,mamicode.com
首页 > 其他好文 > 详细

【待补】splay 模板

时间:2018-08-20 23:00:47      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:clu   eof   来替   efi   color   name   war   wap   print   

#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\n", 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\n"); hehe.query(b, c); }
}

return 0;
}*/

 

【待补】splay 模板

标签:clu   eof   来替   efi   color   name   war   wap   print   

原文地址:https://www.cnblogs.com/SuuT/p/9508423.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!