[BZOJ1954]Pku3764 The xor-longest Path
2016-04-02 22:47
281 查看
Pku3764 The xor-longest Path
Description给定一棵n个点的带权树,求树上最长的异或和路径
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
1 2 3
2 3 4
2 4 6
Sample Output
7
HINT
The xor-longest path is 1->2->3, which has length 7 (=3 ⊕ 4)
注意:结点下标从1开始到N….
Solution
首先我们遇到的一个问题是快速得到任意两点之间路径的异或和的问题。
异或满足交换律和结合律,以0为不变元,这些性质与加法类似,联想加法,我们通常采取sum[u]+sum[v]-sum[lca(u,v)]-sum[lca(u,v)->fa]的方法,再联系异或自身的特殊性质(x^x=0),我们只需要f[u]^f[v]即可
然后我们发现我们需要做的是寻找f[u]^f[v]的最值
这是Trie树的经典问题
Code
#include <bits/stdc++.h> using namespace std; #define rep(i, l, r) for (int i = (l); i <= (r); i++) #define per(i, r, l) for (int i = (r); i >= (l); i--) #define debug(...) fprintf(stderr, __VA_ARGS__) template<typename T> inline void read(T &x){ x = 0; T f = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); } x *= f; } const int INF = 0x7fffffff; const int N = 1e5+100; const int LEN = 35; int bin[LEN], n, f ; struct Node{ int v, c; Node *nxt; }pool[N<<1], *tail=pool, *g ; struct Trie{ Trie *c[2]; }POOL[N*LEN], *TAIL=POOL, *root; inline void ckmax(int &x, int y){ if (x < y) x = y; } inline void addedge(int u, int v, int c){ tail->v = v; tail->c = c; tail->nxt = g[u]; g[u] = tail++; tail->v = u; tail->c = c; tail->nxt = g[v]; g[v] = tail++; } void dfs(int x, int fa){ for (Node *p = g[x]; p; p=p->nxt) if (p->v != fa) { f[p->v] = f[x] ^ p->c; dfs(p->v, x); } } void insert(int x, int p, Trie *&rt){ if (!rt) rt = TAIL++; if (p<0) return; insert(x, p-1, rt->c[(x&bin[p])>>p]); } int query(int x, int p, Trie *rt){ if (p<0) return 0; int d = (x&bin[p])>>p; return rt->c[!d] ? bin[p]+query(x, p-1, rt->c[!d]) : query(x, p-1, rt->c[d]); } int main(){ bin[0] = 1; rep(i, 1, 30) bin[i] = bin[i-1] << 1; read(n); rep(i, 1, n-1){ int u, v, c; read(u); read(v); read(c); addedge(u, v, c); } dfs(1, 0); rep(i, 1, n) insert(f[i], 30, root); int ans = -INF; rep(i, 1, n) ckmax(ans, query(f[i], 30, root)); printf("%d\n", ans); return 0; }
相关文章推荐
- HDU 2196 Computer(树的直径)
- 文件操作->Tesla.Angela教程整理
- centos之jdk安装
- 完美主义容易导致效率低下
- nginx运行时报错:error while loading shared libraries: libpcre.so.3
- 我的2016年Linux学习决心书(老男孩教育在线课程班第一期)
- (十四) Nepxion-Thunder分布式RPC集成框架 - 调用链
- 强连通分量分解
- 算法导论—Trie树
- Android WebView常见问题及解决方案汇总
- 字符串反转的进一步应用----单词反转
- day24 订单删除 & 打印销量排行榜 & 在线支付
- 通过udl文件得到连接字符串
- 重载方法调用精确匹配问题
- OSChina 周日乱弹 ——我18岁了都没睡过男人
- 活动选择
- C++实践参考:IP地址类
- 编码又闹出了小问题
- 2006年清华大学计算机研究生机试真题
- 笔试题——对称二叉树