LGOJ4299 capital

This title is \ (LCT \) maintain sub-tree information \ (LCT \) to maintain the center of gravity

Description

link

Overview meaning of the questions: Given a forest, requires support of the following

1. Link two points

2. seek a point where the tree's center of gravity

3. The center of gravity of all the required number of XOR and

Solution

\[Begin\]

See the link and asks the operator of the subject, we thought \ (LCT \)

The first is the nature of some of the center of gravity, this question can be used:

\ (1 \) distance between the point and the minimum point of the tree is the center of all the points

\ (2 \) center of gravity will move up to a distance of one side after adding an edge

\ (3 \) on a forest path if we Unicom two trees, then the focus of a new tree in the center of gravity of the original two trees

It should be defined by the center of gravity of understanding of what it is easy to prove \ (2333 \)

Then we deal with \ (2 \) put forward a disjoint-set operation time ( \ (the findroot \) seems very slow)

Processing \ (3 \) operation when something similar binary search directly in the chain to see both sides of the magnitude relationship subtree

\[Q.A.D\]

\ (Ps \) Bloggers should know is \ (QED \)

Code

#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 = 3e5 + 10, inf = 1e15 + 10;
int f[N], c[N][2], s[N], st[N], si[N], n, m, fa[N];
bool r[N];
inline void push_up(int x) { return s[x] = s[c[x][1]] + s[c[x][0]] + si[x] + 1, void(); }
inline bool notroot(int x) { return c[f[x]][0] == x || c[f[x]][1] == x; }
inline void push_down(int x) {
    if (r[x]) {
        swap(c[x][0], c[x][1]);
        r[c[x][0]] ^= 1;
        r[c[x][1]] ^= 1;
    }
    return r[x] = 0, void();
}
inline void push_all(int x) {
    if (notroot(x))
        push_all(f[x]);
    push_down(x);
    return;
}
inline void rotate(int x) {
    int y = f[x], z = f[y], k = (c[y][1] == x), w = c[x][!k];
    if (notroot(y))
        c[z][c[z][1] == y] = x;
    c[x][!k] = y;
    c[y][k] = w;
    if (w)
        f[w] = y;
    f[y] = x;
    f[x] = z;
    return push_up(y);
}
inline void splay(int x) {
    push_all(x);
    while (notroot(x)) {
        int y = f[x], z = f[y];
        if (notroot(y))
            rotate((c[y][0] == x) ^ (c[z][0] == y) ? x : y);
        rotate(x);
    }
    return push_up(x);
}
inline void access(int x) {
    for (int y = 0; x; x = f[y = x]) {
        splay(x);
        si[x] += s[c[x][1]], si[x] -= s[c[x][1] = y];
        push_up(x);
    }
    return;
}
inline void makeroot(int x) {
    access(x);
    splay(x);
    r[x] ^= 1;
    return;
}

inline void split(int x, int y) {
    makeroot(x);
    access(y);
    splay(y);
    return;
}
inline void link(int x, int y) {
    split(x, y);
    si[f[x] = y] += s[x];
    push_up(y);
    return;
}
inline int get(int x) { return fa[x] == x ? x : fa[x] = get(fa[x]); }
inline int update(int x) {
    int l, r, ji = s[x] & 1, sum = s[x] >> 1, lsum = 0, rsum = 0, newp = inf, nl, nr;
    while (x) {
        push_down(x);
        nl = s[l = c[x][0]] + lsum;
        nr = s[r = c[x][1]] + rsum;
        if (nl <= sum && nr <= sum) {
            if (ji) {
                newp = x;
                break;
            } else if (newp > x)
                newp = x;
        }
        if (nl < nr)
            lsum += s[l] + si[x] + 1, x = r;
        else
            rsum += s[r] + si[x] + 1, x = l;
    }
    return splay(newp), newp;
}
signed main() {
    int n = read(), m = read(), x, y, z, ans = 0;
    for (int i = 1; i <= n; ++i) s[i] = 1, fa[i] = i, ans ^= i;
    while (m--) {
        string s;
        cin >> s;
        if (s == "A") {
            x = read();
            y = read();
            link(x, y);
            split(x = get(x), y = get(y));
            z = update(y);
            ans = ans ^ x ^ y ^ z;
            fa[x] = fa[y] = fa[z] = z;
        } else if (s == "Xor")
            printf("%lld\n", ans);
        else
            printf("%lld\n", get(read()));
    }
    return 0;
}
}  // namespace yspm
signed main() { return yspm::main(); }

Guess you like

Origin www.cnblogs.com/yspm/p/12375607.html