POJ 3764 The xor-longest( 树上异或前缀和&字典树求最大异或)

In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:

_{xor}length(p)=oplus_{e in p}w(e)

⊕ is the xor operator.

We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?  

Input

The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.

Output

For each test case output the xor-length of the xor-longest path.

Sample Input

4
0 1 3
1 2 4
1 3 6

Sample Output

7

Hint

The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)

题意:

给出一棵树,求树上的最大路径异或和。

思路:

        dfs得到根到节点的异或前缀和,然后把每个点的异或前缀和插入字典树中,就可以按套路,在字典树里找对应的最大异或了。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxm=200010;
const int maxn=3000000;
int Laxt[maxm],Next[maxm],To[maxm],val[maxm],cnt,Xor[maxm];//dfs
int ch[maxn][2],tot,ans,b[40],n;//trie
int q_pow(int a,int x){ int res=1;while(x){if(x&1) res*=a;x>>=1;a*=a;} return res;}
int read()
{
    int res=0; char c=getchar();
    for(;c>'9'||c<'0';c=getchar());
    for(;c<='9'&&c>='0';res=res*10+c-'0',c=getchar()) ;
    return res;
}
void init()
{
    memset(Laxt,0,sizeof(Laxt));
    memset(Xor,0,sizeof(Xor));
    memset(ch,0,sizeof(ch));
    cnt=tot=ans=0;
}
void add(int u,int v,int x)
{
    Next[++cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
    val[cnt]=x;
}
void dfs(int u,int pre,int x)
{
    for(int i=Laxt[u];i;i=Next[i]){
        if(To[i]!=pre){
            Xor[To[i]]=x^val[i];
            dfs(To[i],u,Xor[To[i]]);
        }
    }
}
void insert(int x)
{
    int Now=0; 
    for(int i=0;i<=31;i++) { b[i]=x&1;x>>=1;}
    for(int i=31;i>=0;i--){
        if(!ch[Now][b[i]]) ch[Now][b[i]]=++tot;
        Now=ch[Now][b[i]];
    }
}
void find(int x)
{
    int Now=0,tmp=0;
    for(int i=0;i<=31;i++){ b[i]=x&1; x>>=1; }
    for(int i=31;i>=0;i--){
        if(ch[Now][b[i]^1]) Now=ch[Now][b[i]^1],tmp+=q_pow(2,i);
        else Now=ch[Now][b[i]];
    } ans=max(ans,tmp);
}
void build()
{
    for(int i=1;i<=n;i++) insert(Xor[i]);
    for(int i=1;i<=n;i++) find(Xor[i]);
}
int main()
{
    while(~scanf("%d",&n)){
        init();  int u,v,x;
        for(int i=1;i<n;i++){        
            u=read();v=read();x=read();    
            u++;v++;
            add(u,v,x); add(v,u,x);
        }
        dfs(1,0,0); build();
        printf("%d
",ans);
    } return 0;
}

 

原文地址:https://www.cnblogs.com/hua-dong/p/8252163.html