给定一棵 nn 个点的带权树,结点下标从 11 开始到 nn。寻找树中找两个结点,求最长的异或路径。
异或路径指的是指两个结点之间唯一路径上的所有边权的异或。
处理出每个点的树上异或前缀
这些异或值按照二进制数插入Trie
经典问题了
#include <iostream> #include <cstring> using namespace std; const int N=1e6+10,M=N; int tot=1,ch[N][2]; int n,nxt[M],go[M],hd[N],w[M],all=1; int g[N]; void add_(int x,int y,int z){ go[++all]=y; w[all]=z;nxt[all]=hd[x]; hd[x]=all; } void dfs(int x,int fa){ for(int i=hd[x];i;i=nxt[i]){ int y=go[i],z=w[i]; if(y==fa) continue; g[y]=z^g[x]; dfs(y,x); } } void insert(int num){ int u=1,c; for(int i=31;i>=0;i--){ c=(num>>i)&1; if(ch[u][c]==0) ch[u][c]=++tot; u=ch[u][c]; } } int find(int num){ int u=1,c,t=0; for(int i=31;i>=0;i--){ c=(num>>i)&1; if(ch[u][c^1]) u=ch[u][c^1],t=t*2+1; else u=ch[u][c],t*=2; } return t; } signed main(){ cin>>n; int x,y,z,ans=0; for(int i=1;i<n;i++) cin>>x>>y>>z,add_(x,y,z),add_(y,x,z); dfs(1,0); for(int i=1;i<=n;i++){ ans=max(ans,find(g[i])); insert(g[i]); } cout<<ans; }
标签:ch,int,路径,P4551,异或,num,hd From: https://www.cnblogs.com/towboa/p/17196001.html