FHQ treap板子

感觉这个玩意就是拆来拆去,所以没啥可学习的

粘一下两个题的代码吧

LGOJ 普通平衡树

#include <bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm {
inline int read() {
    int res = 0, f = 1;
    char k;
    while (!isdigit(k = getchar()))
        if (k == '-')
            f = -1;
    while (isdigit(k)) res = res * 10 + k - '0', k = getchar();
    return res * f;
}
const int N = 1e6 + 10, inf = 1e15 + 10;
int base = 12344, tot, rt;
int val[N], ls[N], rs[N], sz[N], rk[N];
inline int random() { return (base *= 102394) %= 239402, base; }
inline int add(int valn) {
    sz[++tot] = 1;
    ls[tot] = rs[tot] = 0;
    val[tot] = valn;
    rk[tot] = random();
    return tot;
}
inline void update(int rt) {
    sz[rt] = sz[ls[rt]] + sz[rs[rt]] + 1;
    return;
}
inline void split(int rt, int &a, int &b, int valn) {
    if (!rt)
        return a = b = 0, void();
    if (val[rt] <= valn)
        a = rt, split(rs[rt], rs[a], b, valn);
    else
        b = rt, split(ls[rt], a, ls[b], valn);
    return update(rt), void();
}
inline void merge(int &rt, int a, int b) {
    if (!b || !a)
        return rt = a + b, void();
    if (rk[a] < rk[b])
        rt = a, merge(rs[rt], rs[a], b);
    else
        rt = b, merge(ls[rt], a, ls[b]);
    return update(rt), void();
}
inline void insert(int &rt, int val) {
    int x = 0, y = 0, now = add(val);
    split(rt, x, y, val);
    merge(x, x, now);
    merge(rt, x, y);
    return;
}
inline void del(int &rt, int val) {
    int x = 0, y = 0, z = 0;
    split(rt, x, y, val);
    split(x, x, z, val - 1);
    merge(z, ls[z], rs[z]);
    merge(x, x, z);
    merge(rt, x, y);
    return;
}
inline int get_kth(int rt, int k) {
    while (sz[ls[rt]] + 1 != k) {
        if (sz[ls[rt]] >= k)
            rt = ls[rt];
        else
            k -= sz[ls[rt]] + 1, rt = rs[rt];
    }
    return val[rt];
}
inline int get_rank(int &rt, int val) {
    int x = 0, y = 0;
    split(rt, x, y, val - 1);
    int tmp = sz[x] + 1;
    merge(rt, x, y);
    return tmp;
}
inline int get_pre(int &rt, int valn) {
    int x = 0, y = 0;
    split(rt, x, y, valn - 1);
    int tmp = get_kth(x, sz[x]);
    merge(rt, x, y);
    return tmp;
}
inline int get_nxt(int &rt, int valn) {
    int x = 0, y = 0;
    split(rt, x, y, valn);
    int tmp = get_kth(y, 1);
    merge(rt, x, y);
    return tmp;
}
signed main() {
    int n = read();
    add(inf);
    tot = 1;
    sz[1] = 0;
    rt = 1;
    while (n--) {
        int opt = read(), valn = read();
        switch (opt) {
            case 1:
                insert(rt, valn);
                break;
            case 2:
                del(rt, valn);
                break;
            case 3:
                printf("%lld\n", get_rank(rt, valn));
                break;
            case 4:
                printf("%lld\n", get_kth(rt, valn));
                break;
            case 5:
                printf("%lld\n", get_pre(rt, valn));
                break;
            case 6:
                printf("%lld\n", get_nxt(rt, valn));
                break;
        }
    }
    return 0;
}
}  // namespace yspm
signed main() { return yspm::main(); }

NOI2015 维护数列

#include <bits/stdc++.h>
#define int long long
using namespace std;
namespace yspm{
    int st[500005], len;
    inline int read() {
        int res = 0, f = 1;
        char k;
        while (!isdigit(k = getchar()))
            if (k == '-')
                f = -1;
        while (isdigit(k)) res = res * 10 + k - '0', k = getchar();
        return res * f;
    }
    struct node {
        int l, r, s, val, cov;
        bool lz, fl;
        int sum, qz, hz, zd;
    } t[500005];
    int id, rt;
    int add(int v) {
        id = st[len--];
        t[id].l = t[id].r = t[id].lz = t[id].cov = 0;
        t[id].s = 1;
        t[id].val = t[id].sum = v;
        t[id].qz = t[id].hz = max(0ll, v);
        t[id].zd = v;
        return id;
    }
    void push_up(int x) {
        if (!x)
            return;
        t[x].s = t[t[x].l].s + t[t[x].r].s + 1;
        t[x].sum = t[t[x].l].sum + t[t[x].r].sum + t[x].val;
        t[x].qz = max(max(t[t[x].l].qz, t[t[x].l].sum + t[x].val + t[t[x].r].qz), 0ll);
        t[x].hz = max(max(t[t[x].r].hz, t[t[x].r].sum + t[x].val + t[t[x].l].hz), 0ll);
        t[x].zd = max(t[x].val, t[x].val + t[t[x].l].hz + t[t[x].r].qz);
        if (t[x].l)
            t[x].zd = max(t[x].zd, t[t[x].l].zd);
        if (t[x].r)
            t[x].zd = max(t[x].zd, t[t[x].r].zd);
    }
    void Reverse(int x) {
        if (!x)
            return;
        swap(t[x].l, t[x].r);
        swap(t[x].hz, t[x].qz);
        t[x].lz ^= 1;
    }
    void Cover(int x, int ci) {
        t[x].val = t[x].cov = ci;
        t[x].sum = t[x].s * ci;
        t[x].qz = t[x].hz = max(0ll, t[x].sum);
        t[x].zd = max(ci, t[x].sum);
        t[x].fl = 1;
    }
    void push_down(int x) {
        if (!x)
            return;
        if (t[x].lz) {
            if (t[x].l)
                Reverse(t[x].l);
            if (t[x].r)
                Reverse(t[x].r);
            t[x].lz = 0;
        }
        if (t[x].fl) {
            if (t[x].l)
                Cover(t[x].l, t[x].cov);
            if (t[x].r)
                Cover(t[x].r, t[x].cov);
            t[x].cov = t[x].fl = 0;
        }
    }
    void del(int x) {
        if (!x)
            return;
        st[++len] = x;
        if (t[x].l)
            del(t[x].l);
        if (t[x].r)
            del(t[x].r);
    }
    void split(int x, int &L, int &R, int K) {
        if (x)
            push_down(x);
        if (!x) {
            L = R = 0;
            return;
        }
        if (t[t[x].l].s + 1 <= K)
            L = x, split(t[x].r, t[L].r, R, K - t[t[x].l].s - 1);
        else
            R = x, split(t[x].l, L, t[R].l, K);
        push_up(x);
    }
    void merge(int x, int y, int &root) {
        if (!x || !y) {
            root = x + y;
            return;
        }
        if (90000008 % (t[x].s + t[y].s) < t[x].s)
            push_down(x), root = x, merge(t[x].r, y, t[root].r), push_up(x);
        else
            push_down(y), root = y, merge(x, t[y].l, t[root].l), push_up(y);
    }
    int n, m;
    int A[500005];
    int build(int l, int r) {
        if (l == r) {
            return add(A[l]);
        }
        int x, mid = (l + r) >> 1;
        merge(build(l, mid), build(mid + 1, r), x);
        return x;
    }
    char opt[10];
    signed main() {
        n = read(), m = read(); 
        for (int i = 1; i <= 500000; ++i) st[++len] = i;
        for (int i = 1; i <= n; ++i) A[i] = read();
        merge(rt, build(1, n), rt);
        while (m--) {
            scanf("%s", opt);
            if (opt[0] == 'I') {
                int pos = read(), tot = read();
                int x, y;
                split(rt, x, y, pos);
                for (int i = 1; i <= tot; ++i) A[i] = read();
                merge(x, build(1, tot), x);
                merge(x, y, rt);
            } else if (opt[0] == 'D') {
                int pos = read(), tot = read();
                int x, y, z;
                split(rt, x, y, pos - 1);
                split(y, y, z, tot);
                del(y);
                merge(x, z, rt);
            } else if (opt[0] == 'M' && opt[2] == 'K') {
                int pos = read(), tot = read(), ci = read();
                int x, y, z;
                split(rt, x, y, pos - 1);
                split(y, y, z, tot);
                Cover(y, ci);
                merge(x, y, x);
                merge(x, z, rt);
            } else if (opt[0] == 'R') {
                int pos = read(), tot = read();
                int x, y, z;
                split(rt, x, y, pos - 1);
                split(y, y, z, tot);
                Reverse(y);
                merge(x, y, y);
                merge(y, z, rt);
            } else if (opt[0] == 'G') {
                int pos = read(), tot = read();
                int x, y, z;
                split(rt, x, y, pos - 1);
                split(y, y, z, tot);
                printf("%d\n", t[y].sum);
                merge(x, y, y);
                merge(y, z, rt);
            } else if (opt[0] == 'M' && opt[2] == 'X') {
                printf("%d\n", t[rt].zd);
            }
        }
        return 0;
    }
}signed main(){return yspm::main();}

猜你喜欢

转载自www.cnblogs.com/yspm/p/12344831.html