P6072 『MdOI R1』Path 题解
看来 P8511 的套路还不怎么推广。来点单
令
令
转化一下问题,求
考虑用相似的套路求
为 或 的祖先。从 爬到根,01 Trie 维护子树内点集,途中统计答案。 。此时 都在 子树外,即 为定值 ,且任意子树的 不劣于其内部子树,所以只需统计满足条件的极大子树即可。
显然每个过程中每个点都只会被加一次,所以复杂度
#include <cstdio>
#include <algorithm>
using namespace std;
struct E
{
int v, w, t;
} e[60050];
struct T
{
int c[2] = {0, 0}, k = 0, v;
} R[2000050];
int n, c, x, y, z, p, q, r = 1, P = 1, a[30050], s[30050], t[30050], f[30050], g[30050], h[30050];
void A(int u, int v, int w)
{
e[++c] = {v, w, h[u]};
h[u] = c;
}
void I(int i, int x)
{
int p = r;
++R[r].k;
for (int i = 30, o; i >= 0; --i)
p = R[p].c[o = x >> i & 1] ? R[p].c[o] : R[p].c[o] = ++P, ++R[p].k;
R[p].v = i;
}
int Q(int &i, int x)
{
int p = r;
for (int i = 30, o; i >= 0; --i)
p = R[p].c[R[R[p].c[o = !(x >> i & 1)]].k ? o : !o];
return x ^ a[i = R[p].v];
}
void D(int u, int k)
{
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k)
f[v] = u, a[v] = a[u] ^ e[i].w, D(v, u);
}
void F1(int u, int k)
{
I(u, a[u]);
q = max(q, Q(z, a[u]));
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k && v != g[u])
F1(v, u);
}
void F2(int u, int k)
{
g[u] = 1;
I(u, a[u]);
q = max(q, Q(z, a[u]));
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k && !g[v])
F2(v, u);
}
void G1(int x)
{
q = 0;
for (int i = 1; i <= n; ++i)
g[i] = 0;
for (int i = x; i != 1; i = f[i])
g[f[i]] = i;
for (int i = r = 1; i <= P; ++i)
R[i].c[0] = R[i].c[1] = R[i].k = 0;
for (int i = P = 1; i != x; i = g[i])
s[i] = q, F1(i, f[i]);
s[x] = q;
}
void G2(int x)
{
q = 0;
for (int i = 1; i <= n; ++i)
g[i] = 0;
for (int i = r = 1; i <= P; ++i)
R[i].c[0] = R[i].c[1] = R[i].k = 0;
for (int i = x; i; i = f[i])
F2(i, f[i]), t[i] = q;
}
void S(int u, int k)
{
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k)
if (g[v])
S(v, u);
else
{
q = 0;
for (int i = r = 1; i <= P; ++i)
R[i].c[0] = R[i].c[1] = R[i].k = 0;
P = 1;
F1(v, u);
t[v] = q;
}
}
int main()
{
scanf("%d", &n);
for (int i = 1, u, v, w; i < n; ++i)
scanf("%d%d%d", &u, &v, &w), A(u, v, w), A(v, u, w);
D(1, 0);
for (int i = 1; i <= n; ++i)
I(i, a[i]);
for (int i = 1; i <= n; ++i)
if (q < (p = Q(z, a[i])))
q = p, x = i, y = z;
for (int i = 1; i <= n; ++i)
s[i] = q;
G1(x);
G1(y);
G2(x);
G2(y);
for (int i = 1; i <= n; ++i)
g[i] = 0;
for (int i = x; i; i = f[i])
g[i] = 1;
for (int i = y; i; i = f[i])
g[i] = 1;
S(1, 0);
q = 0;
for (int i = 2; i <= n; ++i)
q = max(q, s[i] + t[i]);
printf("%d", q);
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具