[洛谷P4551]最長異或路徑
阿新 • • 發佈:2018-11-27
題目大意:求樹上最長的異或路徑
題解:由於異或具有自反性,只需要求出每個節點到根的異或長度,塞進$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; }