题目大意:求树上最长的异或路径
题解:由于异或具有自反性,只需要求出每个节点到根的异或长度,塞进$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 ", ans); return 0; }