【模拟试题】最大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 <bits/stdc++.h>
#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<<i);
        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<<i);
        if(Trie[p].son[!t]){
            p=Trie[p].son[!t];
            ret+=1<<i;
        }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;i<n;i++){
        int 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<<Ans;
    return 0;
}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值