社区讨论

TLE求助

P2056[ZJOI2007] 捉迷藏参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mi86gv2o
此快照首次捕获于
2025/11/21 09:24
4 个月前
此快照最后确认于
2025/11/21 09:24
4 个月前
查看原帖
90分,试过各种卡常(可能是代码本身就有问题) 各位大佬帮帮蒟蒻吧QWQ
CPP
// luogu-judger-enable-o2
#include <cstdio>
#include <cstring>
#include <cctype>
#include <queue>
#define getchar nc
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x) {
    x = 0;
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    while (isdigit(c)) x = x * 10 + (c ^ '0'), c = getchar();
}
void print(int x) {
    if (x > 9) print(x / 10);
    putchar(x % 10 + '0');
}
using namespace std;
const int N = 100001;
const int I = 16;
int head[N], nxt[N << 1], to[N << 1], cnt;
inline void addEdge(int s, int t) { to[++cnt] = t, nxt[cnt] = head[s], head[s] = cnt; }
struct heap {
    priority_queue<int> a, b;
    void push(int x) { a.push(x); }
    void del(int x) { b.push(x); }
    void pop() { while (!b.empty() && a.top() == b.top()) a.pop(), b.pop(); a.pop(); }
    int top() { while (!b.empty() && a.top() == b.top()) a.pop(), b.pop(); return a.top(); }
    int secondTop() { int x = top(); pop(); int y = top(); push(x); return y; }
    int size() { return a.size() - b.size(); }
} A, B[N], C[N];
int f[N], mxpt[N], siz[N], vis[N], isOn[N];
int sum, rt, n, q, num;
int dp[N][I + 1], depth[N];
void initLCA(int u, int fa) {
    depth[u] = depth[fa] + 1;
    dp[u][0] = fa;
    for (int i = 1; i <= I; i++) dp[u][i] = dp[dp[u][i - 1]][i - 1];
    for (int i = head[u]; i; i = nxt[i]) {
        int v = to[i];
        if (v != fa) initLCA(v, u);
    }
}
inline int lca(int u, int v) {
    if (depth[u] < depth[v]) swap(u, v);
    for (int i = I; i >= 0; i--)
        if (depth[dp[u][i]] >= depth[v]) u = dp[u][i];
    for (int i = I; i >= 0; i--)
        if (dp[u][i] != dp[v][i]) u = dp[u][i], v = dp[v][i];
    if (u != v) u = dp[u][0];
    return u;
}
inline int dis(int u, int v) {
    return depth[u] + depth[v] - 2 * depth[lca(u, v)];
}
void getrt(int u, int fa) {
    siz[u] = 1, mxpt[u] = 0;
    for (int i = head[u]; i; i = nxt[i]) {
        int v = to[i];
        if (v == fa || vis[v]) continue;
        getrt(v, u);
        siz[u] += siz[v];
        mxpt[u] = max(siz[v], mxpt[u]);
    }
    mxpt[u] = max(sum - siz[u], mxpt[u]);
    if (mxpt[u] < mxpt[rt]) rt = u;
}
void solve(int u, int fa) {
    C[rt].push(dis(u, f[rt]));
    for (int i = head[u]; i; i = nxt[i]) {
        int v = to[i];
        if (v == fa || vis[v]) continue;
        solve(v, u);
    }
}
inline void pushAns(int u) {
    if (B[u].size() >= 2) A.push(B[u].top() + B[u].secondTop());
}
inline void delAns(int u) {
    if (B[u].size() >= 2) A.del(B[u].top() + B[u].secondTop());
}
void divide(int u) {
    vis[u] = 1;
    B[u].push(0);
    solve(u, 0);
    for (int i = head[u]; i; i = nxt[i]) {
        int v = to[i];
        if (vis[v]) continue;
        rt = 0, sum = siz[v];
        getrt(v, 0), v = rt, f[rt] = u, divide(rt);
        B[u].push(C[v].top());
    }
    pushAns(u);
}
inline void turnOn(int u) {
    --num, isOn[u] = 1;
    delAns(u);
    B[u].del(0);
    pushAns(u);
    for (int i = u; f[i]; i = f[i]) {
        delAns(f[i]);
        B[f[i]].del(C[i].top());
        C[i].del(dis(u, f[i]));
        if (C[i].size()) B[f[i]].push(C[i].top());
        pushAns(f[i]);
    }
}
inline void turnOff(int u) {
    ++num, isOn[u] = 0;
    delAns(u);
    B[u].push(0);
    pushAns(u);
    for (int i = u; f[i]; i = f[i]) {
        delAns(f[i]);
        if (C[i].size()) B[f[i]].del(C[i].top());
        C[i].push(dis(u, f[i]));
        B[f[i]].push(C[i].top());
        pushAns(f[i]);
    }
}
int main() {
    read(n);
    for (int i = 1, a, b; i < n; i++)
        read(a), read(b), addEdge(a, b), addEdge(b, a);
    initLCA(1, 0);
    mxpt[rt] = sum = num = n;
    getrt(1, 0), divide(rt);
    read(q);
    for (int i = 1, tmp; i <= q; i++) {
        if (getchar() == 'G')
            print(num <= 1 ? num - 1 : A.top()), putchar('\n');
        else {
            read(tmp);
            if (isOn[tmp]) turnOff(tmp);
            else turnOn(tmp);
        }
    }
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...