Background:
I find I can't understand the original code.
Title:
For a tree, find the longest XOR path.
Train of thought:
back to summary\text{back to summary}back to summary.
01Trie01\text{Trie}01Trie maintains the template title of the sequence XOR.
Make an exclusive or prefix prefix prefix prefix from root to current point.
Because x {xor} x = 0x \ text {xor} x = 0x {xor} x=0, we need to find a point pair (i,j)(i,j)(i,j) to make prei {xor} pre J pre 65123; I \ text {xor} pre ﹣ jprei {xor} prej ﹣.
How to quickly find a point to make it the largest for each preippre? Iprei.
Greedily think that everyone does not affect each other, so we just need to make the highest possible maximum.
Then build a 01Trie01\text{Trie}01Trie, and find it from top to bottom.
Code:
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; int n,len=0; LL ans=0; struct node2{int x,y,z,next;} a[200010]; int last[100010]; LL pre[100010]; struct node1 { int son[2]; node1(){son[0]=son[1]=0;} } tr[1000010]; void ins(int x,int y,int z) { a[++len]=(node2){x,y,z,last[x]};last[x]=len; } void insert(LL x) { int root=0; for(int i=31;i>=0;i--) { bool tmp=x&(1LL<<i); if(!tr[root].son[tmp]) tr[root].son[tmp]=++len; root=tr[root].son[tmp]; } } LL findmax(LL x) { int root=0; LL sum=0; for(int i=31;i>=0;i--) { bool tmp=x&(1<<i); if(tr[root].son[tmp^1]) root=tr[root].son[tmp^1],sum|=(1<<i); else root=tr[root].son[tmp]; } return sum; } void dfs(int x,int fa) { for(int i=last[x];i;i=a[i].next) { int y=a[i].y; if(y==fa) continue; pre[y]=pre[x]^(LL)a[i].z; dfs(y,x); } } int main() { int x,y,z; scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d %d %d",&x,&y,&z); ins(x,y,z),ins(y,x,z); } dfs(1,0); len=0; for(int i=1;i<=n;i++) insert(pre[i]); for(int i=1;i<=n;i++) ans=max(ans,findmax(pre[i])); printf("%lld",ans); }