jiangly 线段树模板(二)

· · 个人记录

using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
struct SegTree {
    u64 h;
    SegTree *lc, *rc;
};
SegTree *null = new SegTree;
SegTree *newSegTree() {
    SegTree *t = new SegTree;
    *t = *null;
    return t;
}
int n;
std::vector<SegTree *> tree;
std::vector<int> sz, top, dep, parent, a;
std::vector<std::vector<int>> e;
std::vector<u64> w;
SegTree *modify(SegTree *t, int l, int r, int x) {
    SegTree *nt = newSegTree();
    *nt = *t;
    nt->h ^= w[x];
    if (r - l == 1) {
        return nt;
    } else {
        int m = (l + r) / 2;
        if (x < m) {
            nt->lc = modify(nt->lc, l, m, x);
        } else {
            nt->rc = modify(nt->rc, m, r, x);
        }
        return nt;
    }
}
int query(SegTree *t1, SegTree *t2, SegTree *t3, SegTree *t4, int l, int r, int x, int y) {
    if ((t1->h ^ t2->h ^ t3->h ^ t4->h) == 0) {
        return -1;
    }
    if (l >= y || r <= x) {
        return -1;
    }
    if (r - l == 1) {
        return l;
    }
    int m = (l + r) / 2;
    int z = query(t1->lc, t2->lc, t3->lc, t4->lc, l, m, x, y);
    if (z == -1) {
        z = query(t1->rc, t2->rc, t3->rc, t4->rc, m, r, x, y);
    }
    return z;
}
void dfsSz(int u) {
    if (parent[u] != -1)
        e[u].erase(std::find(e[u].begin(), e[u].end(), parent[u]));
    tree[u] = modify(tree[u], 0, n, a[u]);
    sz[u] = 1;
    for (int &v : e[u]) {
        tree[v] = tree[u];
        parent[v] = u;
        dep[v] = dep[u] + 1;
        dfsSz(v);
        sz[u] += sz[v];
        if (sz[v] > sz[e[u][0]])
            std::swap(v, e[u][0]);
    }
}
void dfsHLD(int u) {
    for (int v : e[u]) {
        if (v == e[u][0]) {
            top[v] = top[u];
        } else {
            top[v] = v;
        }
        dfsHLD(v);
    }
}
int lca(int u, int v) {
    while (top[u] != top[v]) {
        if (dep[top[u]] > dep[top[v]]) {
            u = parent[top[u]];
        } else {
            v = parent[top[v]];
        }
    }
    if (dep[u] < dep[v]) {
        return u;
    } else {
        return v;
    }
}