Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 8273 | Accepted: 1720 |
Description
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
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)
Idea: Each point stores the XOR sum of the path to the root node, and the maximum XOR of these values is the answer.
POJ does not open O2, and the vector is too slow. I always thought that the dictionary tree writing was rubbing the TLE to despair. I tried three different dictionary tree writing methods, and the result was that the chain forward star was not fast... Plus I added it before. The ingenious optimization of 297ms ran into the top 5
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 const int MaxN = 100000; 45 int n, p[MaxN + 15]; 46 struct Edge { 47 int v, w; 48 Edge () {} 49 Edge (int v, int w) : v(v), w(w) {} 50 } e[2 * MaxN + 15]; 51 52 int cnt, head[MaxN + 15], nex[MaxN + 15]; 53 void add_edge(int u, int v, int w) { 54 e[++cnt] = Edge(v, w); nex[cnt] = head[u]; head[u] = cnt; 55 e[++cnt] = Edge(u, w); nex[cnt] = head[v]; head[v] = cnt; 56 } 57 void dfs(int x, int pa) { 58 for (int i = head[x]; i; i = nex[i]) { 59 int y = e[i].v; 60 if (y == pa) continue; 61 p[y] = p[x] ^ e[i].w; 62 dfs(y, x); 63 } 64 } 65 int trie[2000015][2], tot; 66 void add(int x) { 67 int p = 1; 68 for (int i = 30; ~i; --i) { 69 int f = x >> i & 1; 70 if (!trie[p][f]) { 71 trie[p][f] = ++tot; 72 trie[tot][0] = trie[tot][1] = 0; 73 } 74 p = trie[p][f]; 75 } 76 } 77 int query(int x) { 78 int p = 1, y = 0; 79 for (int i = 30; ~i; --i) { 80 int f = x >> i & 1; 81 if (trie[p][!f]) { 82 y = y << 1 | !f; 83 p = trie[p][!f]; 84 } else { 85 y = y << 1 | f; 86 p = trie[p][f]; 87 } 88 } 89 return x ^ y; 90 } 91 int getint() { 92 int res = 0; char c = getchar(); 93 while (!isdigit(c)) c = getchar(); 94 while (isdigit(c)) { 95 res = res * 10 + c - '0'; 96 c = getchar(); 97 } 98 return res; 99 } 100 int main() { 101 while (~scanf("%d", &n)) { 102 clr(head, 0), cnt = 0; 103 for (int i = 1; i < n; ++i) { 104 int u, v, w; 105 u = getint(); 106 v = getint(); 107 w = getint(); 108 //scanf("%d%d%d", &u, &v, &w); 109 add_edge(u, v, w); 110 } 111 dfs(0, -1); 112 tot = 1; trie[tot][0] = trie[tot][1] = 0; 113 int ans = 0; 114 for (int i = 0; i < n; ++i) { 115 add(p[i]); 116 int res = query(p[i]); 117 ans = max(ans, res); 118 } 119 printf("%d\n", ans); 120 } 121 return 0; 122 }