指针实现可持久化Treap求调
查看原帖
指针实现可持久化Treap求调
759326
DAMDAM楼主2024/6/29 17:48

调一天了根本调不出来因此求调

#include <algorithm>
#include <cstdio>
#include <random>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
mt19937 Rand;
struct Vertex {
    ll val = 0, sum = 0;
    int siz = 0, cnt = 0;
    bool vis = 0;
    unsigned rank = 0;
    Vertex *son[2] = {};
    Vertex() { son[vis = val = sum = 0] = son[siz = cnt = 1] = nullptr, rank = Rand(); }
    Vertex(const ll &__val) { sum = val = __val, rank = Rand(), son[vis = 0] = son[siz = cnt = 1] = nullptr; }
    void Copy(Vertex *p) { p && (*this = *p, 1); }
} *rt[maxn];

int siz(Vertex *p) { return p ? p->siz : 0; }

ll sum(Vertex *p) { return p ? p->sum : 0; }

void Pushup(Vertex *p) {
    p && (p->siz = siz(*p->son) + siz(p->son[1]) + p->cnt, p->sum = sum(*p->son) + sum(p->son[1]) + p->val);
}

void Maintain(Vertex *p) {
    if (p) {
        Vertex *x = new Vertex;
        x->Copy(p), p = x;
    }
}

void TagRev(Vertex *p) { if (p) p->vis ^= 1; }

void Pushdown(Vertex *p) {
    if (p && p->vis) 
        swap(*p->son, p->son[1]), Maintain(*p->son), Maintain(p->son[1]), 
        TagRev(*p->son), TagRev(p->son[1]), p->vis = 0;
}

void SplitRank(const ll &k, Vertex *&u, Vertex *&v, Vertex *p) {
    if (!p) return void (u = v = nullptr);
    Pushdown(p);
    if (k <= siz(p->son[0])) (v = new Vertex)->Copy(p), SplitRank(k, u, v->son[0], p->son[0]), Pushup(v);
    else (u = new Vertex)->Copy(p), SplitRank(k - siz(p->son[0]) - p->cnt, u->son[1], v, p->son[1]), Pushup(u);
}

void Merge(Vertex *u, Vertex *v, Vertex *&p) {
    if (!u || !v) return void (p = u ? u : v);
    p = new Vertex, Pushdown(u), Pushdown(v);
    if (u->rank >= v->rank) p->Copy(v), Merge(u, p->son[0], p->son[0]);
    else p->Copy(u), Merge(p->son[1], v, p->son[1]);
    Pushup(p);
}

void Update(const ll &k, const ll &x, Vertex *u, Vertex *&v) {
    Vertex *a = nullptr, *c = nullptr;
    SplitRank(k, a, c, u), Merge(new Vertex{x}, c, c), Merge(a, c, v);
}

void Erase(const ll &k, Vertex *u, Vertex *&v) {
    Vertex *a = nullptr, *b = nullptr, *c = nullptr;
    SplitRank(k - 1, a, b, u), SplitRank(1, b, c, b), Merge(a, c, v);
}

void Reverse(const ll &l, const ll &r, Vertex *u, Vertex *&v) {
    Vertex *a = nullptr, *b = nullptr, *c = nullptr;
    SplitRank(l - 1, a, b, u), SplitRank(r - l + 1, b, c, b);
    TagRev(b);
    Merge(b, c, b), Merge(a, b, v);
}

ll Get(const ll &l, const ll &r, Vertex *u, Vertex *&v) {
    Vertex *a = nullptr, *b = nullptr, *c = nullptr;
    SplitRank(l - 1, a, b, u), SplitRank(r - l + 1, b, c, b);
    ll reply = sum(b);
    return Merge(b, c, b), Merge(a, b, v), reply;
}

int main() {
    int n;
    scanf("%d", &n);
    ll last = 0, x, p;
    for (int i = 1, tp, v; i <= n; ++i) {
        scanf("%d%d%lld", &v, &tp, &p), p ^= last;
        if (tp == 2) Erase(p, rt[v], rt[i]);
        else {
            scanf("%lld", &x), x ^= last;
            if (tp == 1) Update(p, x, rt[v], rt[i]);
            else if (tp == 3) Reverse(p, x, rt[v], rt[i]);
            else printf("%lld", last = Get(p, x, rt[v], rt[i])), putchar(10);
        }
    }
    return 0;
}
2024/6/29 17:48
加载中...