最大路径异或和
题目链接:https://www.luogu.com.cn/problem/P4551
题意:
给定义一颗带权树,求其中两个节点边权异或和最大值
思路:
结论是:树上两个节点i,j由于 x ^ x=0 的异或性质,所以其异或和为(根节点,i)路径异或和 xor (根节点,j)路径异或和
所以dfs求出每个节点和根节点的路径异或和,然后拉到01trie跑板子即可
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pb push_back
#define endl "\n"
#define fi first
#define se second
//#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 lll;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const ll llmax=LLONG_MAX;
const int maxn=1e5+5;
const int mod=1e9+7;
struct trie{
int ch[maxn*31][2],idx;
void insert(int x){
int p=0;
for(int i=31;i>=0;i--){
int j= (x>>i)&1;
if(!ch[p][j])ch[p][j]=++idx;
p=ch[p][j];
}
}
int query(int x){
int p=0,res=0;
for(int i=31;i>=0;i--){
int j= (x>>i)&1;
if(ch[p][!j]){
res+= (1<<i);//累加边权
p=ch[p][!j];
}else{
p=ch[p][j];
}
}
return res;
}
};
trie tries;
vector<pii>e[maxn];
int vis[maxn];
int a[maxn];
void dfs(int u,int res){
vis[u]=1;
a[u]=res;
for(auto ed:e[u]){
int v=ed.fi,w=ed.se;
if(!vis[v]){
dfs(v,res^w);
}
}
}
void solve(){
int n;cin>>n;
for(int i=1;i<n;i++){
int u,v,w;cin>>u>>v>>w;
e[u].pb({v,w});
e[v].pb({u,w});
}
dfs(1,0);
for(int i=1;i<=n;i++){
tries.insert(a[i]);
}
int ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,tries.query(a[i]));
}
cout<<ans<<endl;
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0);
int T=1;
while(T--){
solve();
}
return 0;
}