随笔 - 531  文章 - 0  评论 - 3  阅读 - 10215 

给定一棵 nn 个点的带权树,结点下标从 11 开始到 nn。寻找树中找两个结点,求最长的异或路径。

异或路径指的是指两个结点之间唯一路径上的所有边权的异或。

 

处理出每个点的树上异或前缀

 这些异或值按照二进制数插入Trie

经典问题了

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#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;
 }

 

posted on   towboat  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示