【模拟试题】最大Xor路径 Trie

题目描述

  MT神牛非常喜欢出Xor的题,在WC2011的时候,MT神牛出了一道非常经典的Xor最大路径题。
  Bird向MT神牛学习,思考了许多关于Xor路径的问题,有一天,Bird想到了一个问题,给出一个序列,求这个序列的连续子序列的Xor值最大。
  如1 3 4 8,最大的Xor子序列当然是3 xor 4 xor 8=15了。
  Bird实在太强大了,这个问题怎么能难住他呢?于是Bird又开始思考了,如果是一颗树呢,如何求出这棵带边权的树的一条最大Xor路径呢?但是谁都知道Bird实在太强大了,马上想到了解决这个问题的高效算法,但是Bird总是不愿去机房写代码,于是他把这个easy的问题,交给了你,希望你能尽快帮他写完代码。

题目大意

求树上异或和的最大值。

数据范围

【数据规模】
  对于40%的数据,数据退化为一条链
  除上述的40%的数据外,还有10%的数据N<=1000
  100%的数据满足2 <= n <= 100000,1 < a,b <= N,C <= 2^31-1

样例输入

4
1 2 3
1 3 4
1 4 7

样例输出

7

解题思路

  其实树上的异或和最大值和数列上的最大值并没有什么区别。设f[x]为从根到x节点的异或和,x到y的异或和等于f[x]^f[y],因为x,y的lca部分的异或和正好抵消掉了。数列上的异或和最大值就是建一棵Trie树,枚举每个数在Trie树上找。
  其实代码也挺短的qwq

代码

#include 
#define Maxn 100005
using namespace std;
inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
int h[Maxn],f[Maxn],cnt=0;
struct node{int to,next,v;}e[Maxn*2];
void AddEdge(int x,int y,int v){e[++cnt]=(node){y,h[x],v};h[x]=cnt;}
struct trie{int son[2];}Trie[Maxn*32];
void Insert(int x){
    int p=0;
    for(int i=31;~i;i--){
        bool t=x&(1<if(!Trie[p].son[t])Trie[p].son[t]=++cnt;
        p=Trie[p].son[t];
    }
}
int Ask(int x){
    int ret=0,p=0;
    for(int i=31;~i;i--){
        bool t=x&(1<if(Trie[p].son[!t]){
            p=Trie[p].son[!t];
            ret+=1<else p=Trie[p].son[t];
    }
    return ret;
}
void dfs(int x,int L,int S){
    f[x]=S;
    for(int p=h[x];p;p=e[p].next){
        int y=e[p].to;
        if(y==L)continue;
        Insert(S^e[p].v);
        dfs(y,x,S^e[p].v);
    }
}
int main(){
    memset(Trie,0,sizeof(Trie));
    int n=Getint(),Ans=0;
    for(int i=1;iint x=Getint(),y=Getint(),v=Getint();
        AddEdge(x,y,v);
        AddEdge(y,x,v);
    }
    cnt=0;
    dfs(1,0,0);
    for(int i=1;i<=n;i++)Ans=max(Ans,Ask(f[i]));
    cout<return 0;
}

转载于:https://www.cnblogs.com/Cedric341561/p/6810995.html

你可能感兴趣的:(【模拟试题】最大Xor路径 Trie)