BZOJ 1954: Pku3764 The xor-longest Path(01trie)

求树上最长异或路径.

根据异或的性质,我们知道a^a=0,那么a^b^b^c=a^c;

所以我们随便找个点做根,然后dfs出每个点到根的异或路径长num[i],对于任意两点有两种情况,当根是他们的LCA时,那么两点异或路径和就直接是num[i]^num[j],不是LCA时,由于两条路径都包含了LCA到根的路径,两次异或抵消掉了,所以证得任意两点异或路径和为num[i]^num[j];

所以把num[i]扔到trie里搞一搞就行了...

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%d",a)
10 #define writeln printf("\n")
11 const int N=1e5+50;
12 const int MOD=1e9+7;
13 using namespace std;
14 int n;
15 int x,y,z;
16 int st,tot=1,ans=-23333333;
17 int head[N],c[N];
18 int trie[N*31][2];
19 bool vis[N];
20 struct edge
21 {
22     int to,nxt,cost;
23 }edge[N<<1];
24 void add(int x,int y,int z)
25 {
26     edge[++tot].to=y;
27     edge[tot].cost=z;
28     edge[tot].nxt=head[x];
29     head[x]=tot;
30 }
31 int read()
32 {
33     int s=0,t=1; char c;
34     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
35     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
36     return s*t;
37 }
38 ll readl()
39 {
40     ll s=0,t=1; char c;
41     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
42     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
43     return s*t;
44 }
45 void dfs(int x)
46 {
47     int y;
48     for (int i=head[x];i;i=edge[i].nxt){
49       y=edge[i].to;
50       if (!vis[y]){
51         vis[y]=true;
52         c[y]=c[x]^edge[i].cost;
53         dfs(y);
54       }
55     }
56 }
57 void insert(int x)
58 {
59     int u=1;
60     for (int i=31;i>=0;i--){
61       int c=((1<<i)&x)>0;
62       if (!trie[u][c]) trie[u][c]=++tot;
63       u=trie[u][c];
64     }
65 }
66 int find(int x)
67 {
68     int u=1;
69     int res=0;
70     for (int i=31;i>=0;i--){
71       int c=((1<<i)&x)>0;
72       if (trie[u][1-c]) u=trie[u][1-c],res+=(1<<i);    
73       else u=trie[u][c];
74     }
75     return res;
76 }
77 int main()
78 {
79     n=read(); memset(vis,false,sizeof(vis));
80     for (int i=1;i<n;i++){
81       x=read(),y=read(),z=read();
82       add(x,y,z); add(y,x,z);
83       if (i==1) st=x;
84     }
85     dfs(st);
86     for (int i=1;i<=n;i++)
87       if (c[i]) {
88           ans=max(ans,c[i]);
89         ans=max(ans,find(c[i]));
90         insert(c[i]);
91       }
92     out(ans);
93     return 0;
94 }
95         
View Code

 

posted @ 2018-08-30 23:08  Kaleidoscope233  阅读(115)  评论(0编辑  收藏  举报