标签:seve follow xor sum can 定义 target xor def 转化
题目链接:http://poj.org/problem?id=3764
Time Limit: 2000MS Memory Limit: 65536K
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:
$\oplus$ 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 \oplus 4$
题意:
对一棵带权树,我们定义树上的某条路径 $p$ 的“异或长度”为该路径上所有边的边权的异或值。要求你找出树上“异或长度”最长的路径,并求出其“异或长度”。
题解:
显然对于树上任意节点 $x$,我们可以用DFS递推地求出 $dist[x] = dist[par[x]] \oplus w(par[x],x)$。
我们可以枚举所有路径的两个端点 $x,y$,其路径为 $x \sim LCA(x,y) \sim y$。
那么根据异或的性质,就有 $_{xor}length(x \sim y) = dist[x] \oplus dist[y]$,因为 $_{xor}length(root \sim LCA(x,y))$ 这一段同时出现在 $dist[x]$ 和 $dist[y]$ 中,异或之后即为 $0$,正好抵消掉了。
因此,问题就转化为对于长度为 $n$ 的序列 $dist[1] \sim dist[n]$,寻找某一对 $(x,y)$ 使得 $dist[x] \oplus dist[y]$ 最大,给出最大值。该问题即CH 1602 - The XOR Largest Pair - [字典树变形]。
AC代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=1e5+10; int n; struct Edge{ int u,v,w; int next; }; Edge E[2*maxn]; int head[maxn],ne; void init() { ne=0; memset(head,0,sizeof(head)); } void addedge(int u,int v,int w) { ++ne; E[ne].u=u, E[ne].v=v, E[ne].w=w; E[ne].next=head[u]; head[u]=ne; } int d[maxn]; bool vis[maxn]; void dfs(int u) { vis[u]=1; for(int i=head[u];i;i=E[i].next) { if(!vis[E[i].v]) { d[E[i].v]=d[u]^E[i].w; dfs(E[i].v); } } } namespace Trie { const int SIZE=maxn*32; int sz; struct TrieNode { int ed; int nxt[2]; }trie[SIZE]; void init() { sz=1; memset(trie,0,sizeof(trie)); } void insert(int x) { int p=1; for(int k=30;k>=0;k--) { int ch=(x>>k)&1; if(trie[p].nxt[ch]==0) trie[p].nxt[ch]=++sz; p=trie[p].nxt[ch]; } } int MaxXor(int x) { int res=0; int p=1; for(int k=30;k>=0;k--) { int ch=(x>>k)&1; if(trie[p].nxt[ch^1]) { p=trie[p].nxt[ch^1]; res|=1<<k; } else p=trie[p].nxt[ch]; } return res; } }; int main() { while(cin>>n) { init(); for(int i=1,u,v,w;i<n;i++) { scanf("%d%d%d",&u,&v,&w); addedge(u+1,v+1,w); addedge(v+1,u+1,w); } memset(vis,0,sizeof(vis)); memset(d,0,sizeof(d)); dfs(1); Trie::init(); int ans=0; for(int i=1;i<=n;i++) { Trie::insert(d[i]); ans=max(ans,Trie::MaxXor(d[i])); } cout<<ans<<endl; } }
POJ 3764 - The xor-longest Path - [DFS+字典树变形]
标签:seve follow xor sum can 定义 target xor def 转化
原文地址:https://www.cnblogs.com/dilthey/p/9932409.html