社区讨论
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 条回复,欢迎继续交流。
正在加载回复...