链接:https://www.acwing.com/problem/content/146/
这是我今天复习trie树时做的一道题,思路是先计算出每个点一直异或到根节点的异或和,我们记为Dx,那么Dx和Dy进行异或就是x点到y点的异或和了。然后问题转化为n个数字,任取两个的数字进行异或最后答案可以是多大。对于每一个数字转化为32位二进制数,存入到trie树当中
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll ans=0;
int n,b[150000],a[40],trie[5000000][2],tot=1;
vector<pair<int,int>>G[150000];
void dfs(int now,int fa,int num){
b[now]=num;
for(auto seg:G[now]){
int v=seg.first,w=seg.second;
if(v==fa) continue;
dfs(v,now,num^w);
}
}
void get(){
int p=1;ll res=0;
for(int i=31;i>=1;i--){
int ch=a[i];
if(trie[p][ch^1]){
res+=(1<<(i-1));
p=trie[p][ch^1];
}
else p=trie[p][ch];
}
ans=max(ans,res);
}
void insert(){
int p=1;
for(int i=31;i>=1;i--){
int ch=a[i];
if(trie[p][ch]==0) trie[p][ch]=++tot;
p=trie[p][ch];
}
}
int main(){
cin>>n;
for(int i=1;i<n;i++){
int u,v,w;
cin>>u>>v>>w;
u++,v++;
G[u].push_back(make_pair(v,w)),G[v].push_back(make_pair(u,w));
}
dfs(1,0,0);
bool flag=0;
for(int i=1;i<=n;i++){
int x=b[i];
for(int j=30;j>=0;j--){
a[j+1]=(x>>j)&1;
}
if(flag) get();
insert();
flag=1;
}
cout<<ans;
return 0;
}
Comments | NOTHING