最大路径异或和

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


posted @ 2025-03-13 19:37  Marinaco  阅读(14)  评论(0)    收藏  举报
//雪花飘落效果