题目大意:求树上最长的异或路径
题解:由于异或具有自反性,只需要求出每个节点到根的异或长度,塞进$Trie$里,最后对每个节点找一下最大值更新答案即可
卡点:把动态开点写成了可持久化,然后空间要再多开一点(比层数多一)
C++ Code:
#include <algorithm>
#include <cstdio>
#define M 30
#define maxn 100010
#define N (maxn * (M + 1))
int head[maxn], cnt;
struct Edge {
int to, nxt, w;
} e[maxn << 1];
inline void addedge(int a, int b, int c) {
e[++cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
e[++cnt] = (Edge) {a, head[b], c}; head[b] = cnt;
}
int nxt[N][2], root, idx;
void insert(int &rt, int x, int dep) {
if (!rt) rt = idx++;
if (!~dep) return ;
insert(nxt[rt][x >> dep & 1], x, dep - 1);
}
int query(int x) {
int res = 0, rt = root;
for (int i = M; ~i; i--) {
int tmp = x >> i & 1;
if (nxt[rt][!tmp]) rt = nxt[rt][!tmp], res |= 1 << i;
else rt = nxt[rt][tmp];
}
return res;
}
int n, dis[maxn];
void dfs(int u, int fa = 0) {
insert(root, dis[u], M);
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa) {
dis[v] = dis[u] ^ e[i].w;
dfs(v, u);
}
}
}
int main() {
scanf("%d", &n);
for (int i = 1, a, b, c; i < n; i++) {
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, c);
}
dfs(1);
int ans = 0;
for (int i = 1; i <= n; i++) ans = std::max(ans, query(dis[i]));
printf("%d\n", ans);
return 0;
}