题目链接: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;
}