求助卡常
查看原帖
求助卡常
486001
Knighthood楼主2023/4/4 22:31

RT,70pts,吸了氧可以AC

//
// Created by kcx on 04/04/2023
//

#include <bits/stdc++.h>

using namespace std;

const int maxN = 1e5 + 5;

int n;
int num, h[maxN], nex[maxN << 1], to[maxN << 1];
int dep[maxN], f[maxN];
int dp[maxN], sz[maxN], dfa[maxN];
int global, top[maxN], son[maxN];
int vis[maxN], sta[maxN];
priority_queue<int> fIn[maxN], fDe[maxN], sIn[maxN], sDe[maxN]; // All "as"
// f: As a father, answers to sons
// s: As a son, answers to father
// Please don't name these queues in similar names, okay?
// I have been fallen into the pit since two hours ago!
// Oh! God damage! ***!
// Names which I named are much clearer!

inline void edge(int a, int b) {
    to[++num] = b;
    nex[num] = h[a];
    h[a] = num;
}

void pre1(int u, int fa) {
    dep[u] = dep[fa] + 1;
    sz[u] = 1;
    f[u] = fa;
    for (int i = h[u]; i; i = nex[i]) {
        int v = to[i];
        if (v == fa) continue;
        pre1(v, u);
        sz[u] += sz[v];
        if (sz[son[u]] < sz[v]) son[u] = v;
    }
}

void pre2(int u, int sp) {
    top[u] = sp;
    if (son[u]) pre2(son[u], sp);
    for (int i = h[u]; i; i = nex[i]) {
        int v = to[i];
        if (v == f[u] || v == son[u]) continue;
        pre2(v, v);
    }
}

inline int getLca(int a, int b) {
    while (top[a] != top[b]) {
        if (dep[top[a]] < dep[top[b]]) swap(a, b);
        a = f[top[a]];
    }
    return dep[a] < dep[b] ? a : b;
}

inline int getDis(int u, int v) {
    return dep[u] + dep[v] - (dep[getLca(u, v)] << 1);
}

int getRoot(int u, int fa, int sum) {
    sz[u] = 1, dp[u] = 0;
    int minn(0x3f3f3f3f), res;
    for (int i = h[u]; i; i = nex[i]) {
        int v = to[i];
        if (v == fa || vis[v]) continue;
        int tmp = getRoot(v, u, sum);
        sz[u] += sz[v];
        dp[u] = max(dp[u], sz[v]);
        if (minn > dp[tmp]) minn = dp[tmp], res = tmp;
    }
    dp[u] = max(dp[u], sum - dp[u]);
    if (minn > dp[u]) res = u;
    return res;
}

void rebuild(int u, int fa) {
    dfa[u] = fa;
    vis[u] = 1;
    for (int i(h[u]); i; i = nex[i]) {
        int v(to[i]);
        if (vis[v]) continue;
        rebuild(getRoot(v, u, sz[v]), u);
    }
}

inline void clearRedundant(priority_queue<int> &x, priority_queue<int> &y) {
    while (!x.empty() && !y.empty() && x.top() == y.top()) x.pop(), y.pop();
}

inline int getLongest(priority_queue<int> &x, priority_queue<int> &y) {
    clearRedundant(x, y);
    if (x.empty()) return -1;
    int one(x.top());
    x.pop();
    clearRedundant(x, y);
    if (x.empty()) return x.emplace(one), -1;
    int two(one + x.top());
    x.emplace(one);
    return two;
}

inline void change(int x) {
    int u(x);
    while (dfa[u]) {
        int dis(getLongest(fIn[dfa[u]], fDe[dfa[u]]));
        if (dis != -1) fDe[0].emplace(dis);
        dis = getDis(x, dfa[u]);
        if (!sIn[u].empty()) fDe[dfa[u]].emplace(sIn[u].top());
        if (sta[x]) // 1 turn into 0
            sDe[u].emplace(dis);
        else // 0 turn into 1
            sIn[u].emplace(dis);
        clearRedundant(sIn[u], sDe[u]);
        if (!sIn[u].empty()) fIn[dfa[u]].emplace(sIn[u].top());
        dis = getLongest(fIn[dfa[u]], fDe[dfa[u]]);
        if (dis != -1) fIn[0].emplace(dis);
        u = dfa[u];
    }
    if (sta[x]) --global;
    else ++global;
    sta[x] ^= 1;
}

static char buf[1000000],*p1=buf,*p2=buf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++

template <typename T>
void read(T &bow) {
	T xdd = 0, fhh = 1;
	char ch = char(getchar());
	for(; ch < '0' || ch > '9'; ch = char(getchar()))
		if(ch == '-')
			fhh = -1;
	for(; ch >= '0' && ch <= '9'; ch = char(getchar()))
		xdd = (xdd << 1) + (xdd << 3) + (ch ^ 48);
	bow = xdd * fhh;
}

template <typename T>
void write(T xdd) {
    if (!xdd) return putchar('0'), void();
    char F[114];
    int lZj(0);
    T tmp = xdd < 0 ? -xdd : xdd;
    if (xdd < 0) putchar('-');
    while (tmp) {
        F[++lZj] = tmp % 10 ^ 48;
        tmp /= 10;
    }
    while (lZj) putchar(F[lZj--]);
}

int main() {
#define LOCAL
#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif

    read(n);
    for (int i(1); i < n; ++i) {
        int u, v;
        read(u), read(v);
        edge(u, v), edge(v, u);
    }
    pre1(1, 0), pre2(1, 1);
    rebuild(getRoot(1, 0, n), 0);
    for (int i(1); i <= n; ++i) change(i);
    int m;
    read(m);
    while (m--) {
        char op;
        while (op = char(getchar()), (op != 'C' && op != 'G'));
        if (op == 'G') {
            if (global <= 1) write(global - 1), putchar(10);
            else {
                clearRedundant(fIn[0], fDe[0]);
                write(fIn[0].top()), putchar(10);
            }
        } else {
            int x;
            read(x);
            change(x);
        }
    }

    return 0;
}
2023/4/4 22:31
加载中...