POJ 3764 The xor-longest Path 字典树 异或性质
2014-11-16 23:27
405 查看
题意:给出一棵树,每条边上都有权值。求在树上的一条路径,使在这条路径上的异或和最大。
思路:对于异或,我们要考虑其二进制分解。
因为异或满足结合性,所以xorsum[u,v] = xorsum[0,u] ^ xorsum[0,v];我们将任意一点作为根,这样xorsum[0.v]就能dfs求出。
同样,由于上面的公式,对于任意一点u的到其他路径的异或和的最大值,其实就是相当于查询其他的所有的xorsum[0,v]和xorsum[0,v]的最大值。这个转化成了在N个数中查找和给定数异或和最大的值。这个可以用字典树来加速查询,复杂度为O(32)。
复杂度:O(32N).
代码如下:
思路:对于异或,我们要考虑其二进制分解。
因为异或满足结合性,所以xorsum[u,v] = xorsum[0,u] ^ xorsum[0,v];我们将任意一点作为根,这样xorsum[0.v]就能dfs求出。
同样,由于上面的公式,对于任意一点u的到其他路径的异或和的最大值,其实就是相当于查询其他的所有的xorsum[0,v]和xorsum[0,v]的最大值。这个转化成了在N个数中查找和给定数异或和最大的值。这个可以用字典树来加速查询,复杂度为O(32)。
复杂度:O(32N).
代码如下:
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAX = 100010; struct edge{ int to,w; edge(){} edge(int t, int ww):w(ww),to(t){} } edges[MAX<<1]; int head[MAX],nxt[MAX<<1],tot,N,xo[MAX]; char str[40]; void init() { tot = 0; memset(head,-1,sizeof(head)); } void addedge(int u, int v, int w) { edges[tot] = edge(v,w); nxt[tot] = head[u], head[u] = tot++; edges[tot] = edge(u,w); nxt[tot] = head[v], head[v] = tot++; } void dfs(int u, int fa) { for(int i = head[u]; ~i; i = nxt[i]){ edge & e = edges[i]; if(e.to == fa) continue; xo[e.to] = xo[u] ^ e.w; dfs(e.to,u); } } void tostr(int n) { for(int i = 31; i >= 0; --i) str[i] = n % 2 + '0', n >>= 1; str[32] = 0; } int tonum() { int t = 1,ans = 0; for(int i = 31; i >= 0; --i) ans += (str[i] - '0') * t, t *= 2; return ans; } struct Trie{ static const int CHARSET = 2; static const int BASE = '0'; static const int MAXNODE = 4000000; int child[MAXNODE][CHARSET]; int v[MAXNODE]; int root,sz; int id; Trie(){init();} void init(){ root = 1,sz = 1,id = 1; memset(child[1],0,sizeof(child[1])); memset(v,0,sizeof(v)); } void insert(char * s){ int * cur = & root; for(char *p = s; *p; ++p){ cur = &child[*cur][*p - BASE]; if(*cur == 0){ *cur = ++sz; memset(child[*cur],0,sizeof(child[*cur])); } } } int query(int num){ tostr(num); int * cur = & root; for(char * p = str; *p ; ++p){ int c = (*p - BASE) ^ 1; if(child[*cur][c] != 0){ *p += c; cur = &child[*cur][c]; } else{ cur = &child[*cur][c^1]; *p = '0'; } } return tonum(); } } trie; int main(void) { int u,v,w; //freopen("input.txt","r",stdin); while(~scanf("%d",&N)){ init(); for(int i = 0; i < N - 1; ++i){ scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } xo[0] = 0; dfs(0,-1); trie.init(); for(int i = 0; i < N; ++i){ tostr(xo[i]); trie.insert(str); } int ans = 0; for(int i = 0; i < N; ++i) ans = max(ans,trie.query(xo[i])); printf("%d\n",ans); } return 0; }
相关文章推荐
- POJ 3764 The xor-longest Path 字典树求最大异或
- POJ 3764 The xor-longest Path ( 字典树应用—— 求连续段相异或最大最小的线性算法)(好题)
- POJ 3764 The xor-longest Path (字典树)
- poj 3764 The xor-longest Path(字典树)
- POJ 3764 The xor-longest Path 01字典树 邻接表
- POJ 3764 The xor-longest Path【字典树】
- POJ 3764 The xor-longest( 树上异或前缀和&字典树求最大异或)
- POJ 3764 The xor-longest Path(字典树 + 贪心)
- ACM学习历程—POJ 3764 The xor-longest Path(xor && 字典树 && 贪心)
- POJ_3764_The xor-longest Path(01字典树)
- poj 3764 The xor-longest Path(字典树)
- POJ 3764 The xor-longest Path (01字典树 + DFS)
- Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值
- bzoj 1954 & poj 3764 The xor-longest Path dfs+Trie
- 【POJ 3764】The xor-longest Path 中文题意&题解&代码(C++)
- POJ 3764[The xor-longest Path]题解
- 1954: Pku3764 The xor-longest Path 0-1字典树
- [POJ 3764] The xor-longest Path (Tire树 + 贪心)
- POJ 3764 The xor-longest Path 01字典树+dfs
- Poj 3764 The xor-longest Path(Trie树+xor+贪心)