可惜没如果=_=
时光的河入海流

题目链接在这里:P4551 最长异或路径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

是一道比较经典的问题,对于异或问题经常会使用01trie树来解决。

当然01trie树只是用来统计答案,往往还需要一些预处理操作。

比如此题需要把从当前点到根节点的路径的异或和求出来,讨论与根节点的联系在树的问题中很常见。

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 const int MAX=1e6+5;
 4 int n;
 5 int tot,head[MAX],adj[MAX],nxt[MAX],wei[MAX];
 6 int val[MAX];
 7 void addedge(int u,int v,int w){
 8     tot++;
 9     adj[tot]=v;
10     wei[tot]=w;
11     nxt[tot]=head[u];
12     head[u]=tot;
13 }
14 void dfs(int x,int fa){
15     int i,j;
16     for (i=head[x];i;i=nxt[i]){
17         if (adj[i]==fa) continue;
18         val[adj[i]]=val[x]^wei[i];
19         dfs(adj[i],x);
20     }
21 }
22 struct Str{
23     int str[MAX][2],cnt;
24     bool vis[MAX];
25     Str(){
26         memset(str,0,sizeof(str));
27         cnt=0;
28         memset(vis,false,sizeof(vis));
29     }
30     void insert(int x){
31         int i,j,p=0;
32         bool zt;
33         for (i=30;i>=0;i--){
34             zt=(1<<i)&x;
35             if (str[p][zt]==0){
36                 str[p][zt]=++cnt;
37                 p=cnt;
38             }
39             else p=str[p][zt];
40         }
41         vis[p]=true;
42     }
43     int check(int v){
44         int i,j,p=0,ans=0;
45         bool zt;
46         for (i=30;i>=0;i--){
47             zt=v&(1<<i);
48             if (str[p][!zt]){
49                 ans+=(1<<i);
50                 p=str[p][!zt];
51             }
52             else p=str[p][zt];
53 //            cout<<p<<endl; 
54         }
55 //        cout<<v<<' '<<ans<<endl;
56         return ans;
57     }
58 }ss;
59 int main(){
60     int i,j,u,v,w,ans=0;
61     scanf("%d",&n);
62     memset(head,0,sizeof(head));
63     memset(val,0,sizeof(val));
64     for (i=1;i<n;i++){
65         scanf("%d%d%d",&u,&v,&w);
66         addedge(u,v,w);
67         addedge(v,u,w);
68     }
69     dfs(1,0);
70 //    for (i=1;i<=n;i++)
71 //        cout<<i<<" : "<<val[i]<<endl; 
72     for (i=1;i<=n;i++)
73         ss.insert(val[i]);
74     for (i=1;i<=n;i++)
75         ans=max(ans,ss.check(val[i]));
76     printf("%d\n",ans);
77     return 0;
78 }

 

posted on 2022-11-18 11:07  珍珠鸟  阅读(17)  评论(0编辑  收藏  举报