In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:
⊕ is the xor operator.
We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?
Input
The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.
Output
For each test case output the xor-length of the xor-longest path.
Sample Input
4 0 1 3 1 2 4 1 3 6
Sample Output
7
Hint
The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)
任意一条路径中的长度异或等会0到u的长度异或 异或上 0到v的长度异或。这样的话我们算出0到所有点的长度异或然后挨个去尝试就好了。
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <vector>
const int M = 200010;
using namespace std;
int n, e;
struct node {
int v, w, next;
}edge[M * 2];
int head[M], dis[M];
int nex[M * 20][2], val[M * 20], tot = 0;
void insert(int x) {
int root = 0;
for (int i = 30; i >= 0; i--) {
int t = (x >> i) & 1;
if (nex[root][t] == 0)
nex[root][t] = ++tot;
root = nex[root][t];
}
val[root] = x;
}
int query(int x) {
int root = 0;
for (int i = 30; i >= 0; i--) {
int t = (x >> i) & 1;
if (nex[root][t ^ 1] != 0) {
root = nex[root][t ^ 1];
}
else root = nex[root][t];
}
return val[root];
}
void dfs(int u, int fa) {
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].v;
int w = edge[i].w;
if (v == fa)continue;
dis[v] = dis[u] ^ w;
dfs(v, u);
}
}
void init() {
for (int i = 0; i <= tot; i++) {
nex[i][0] = nex[i][1] = 0;
}
tot = 0;
}
int main() {
while (scanf("%d", &n) != EOF) {
e = 0;
memset(head, -1, sizeof(head));
for (int i = 1; i < n; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
edge[e].v = v; edge[e].next = head[u]; edge[e].w = w; head[u] = e++;
edge[e].v = u; edge[e].next = head[v]; edge[e].w = w; head[v] = e++;
}
init();
dis[0] = 0;
dfs(0, -1);
int ans = 0;
for (int i = 0; i < n; i++) {
ans = max(ans, dis[i] ^ query(dis[i]));
insert(dis[i]);
}
printf("%d\n", ans);
}
return 0;
}