BZOJ 1954: Pku3764 The xor-longest Path(贪心+trie)
解题思路
\(trie\)的一个比较经典的应用,首先把每个点到根的异或和算出,然后建一棵\(trie\)把所有权值插入到\(Trie\)中,之后枚举所有结点,在\(Trie\)上贪心的跑统计答案,时间复杂度\(O(nlogn)\)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100005;
inline int rd(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
}
int n,head[N],cnt,to[N<<1],nxt[N<<1],val[N<<1];
int tot,ans,res,w[N],rt;
struct Trie{
int ch[N*40][2];
void insert(int &x,int d,int now){
if(!x) x=++tot; if(!d) return;
if((1<<(d-1))&now) insert(ch[x][1],d-1,now);
else insert(ch[x][0],d-1,now);
}
void query(int x,int d,int now){
if(!d) return;
if((1<<(d-1))&now) {
if(ch[x][0]) res|=(1<<(d-1)),query(ch[x][0],d-1,now);
else query(ch[x][1],d-1,now);
}
else {
if(ch[x][1]) res|=(1<<(d-1)),query(ch[x][1],d-1,now);
else query(ch[x][0],d-1,now);
}
}
}tree;
inline void add(int bg,int ed,int w){
to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=w,head[bg]=cnt;
}
void dfs(int x,int F){
for(int i=head[x];i;i=nxt[i]){
int u=to[i]; if(u==F) continue;
w[to[i]]=(w[x]^val[i]); dfs(u,x);
}
}
int main(){
n=rd(); int x,y,z;
for(int i=1;i<n;i++){
x=rd(),y=rd(),z=rd();
add(x,y,z),add(y,x,z);
}
dfs(1,0);
for(int i=1;i<=n;i++) tree.insert(rt,31,w[i]);
for(int i=1;i<=n;i++)
res=0,tree.query(rt,31,w[i]),ans=max(ans,res);
printf("%d\n",ans);
return 0;
}