Trie

作者: Tsukinousag | 来源:发表于2020-03-13 21:05 被阅读0次
    • The xor-longest Path

      dp[x]表示根节点到 x 的路径上所有边权的 xor 值 ,显然有:
      dp[x] = dp[fa[x]] ^ w(x,fa(x))
      可以对树进行一次dfs,求出所有的 dp[x]
      树上 x 到 y 的路径上所有边权的 xor 值结果就等于 dp[x] ^dp[y]
      这是因为根据 xor 运算的性质。“x 到根”和 “y 到根”这两条路径重叠的部分,恰好抵消掉
      所以,问题就变成了从 dp[1] ~ dp[N] 这 N 个数中选出两个, xor 的值最大,可以用 Trie 树快速解决。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int ne[N<<1],e[N<<1],h[N],w[N<<1];
    int son[N*32][2],idx;
    int dp[N];
    void add(int a,int b,int c)
    {
        e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
    }
    void dfs(int u,int fa,int sum)//当前节点,父节点.
    {
        dp[u]=sum;
        for(int i=h[u];~i;i=ne[i])
        {
            int v=e[i];
            if(v!=fa)
                dfs(v,u,sum^w[i]);
        }
    }
    void Insert(int k)
    {
        int p=0;
        for(int i=30;~i;i--)
        {
           int temp=k>>i&1;
           if(!son[p][temp])
               son[p][temp]=++idx;
           p=son[p][temp];
        }
    }
    int Query(int k)
    {
        int p=0,res=0;
        for(int i=30;~i;i--)
        {
            int temp=k>>i&1;
            if(son[p][!temp])
            {
                res+=1<<i;
                p=son[p][!temp];
            }
            else
                p=son[p][temp];
        }
        return res;
    }
    int main()
    {
        int n;
        cin>>n;
        memset(h,-1,sizeof h);
        for(int i=0;i<n-1;i++)
        {
            int x,y,z;
            cin>>x>>y>>z;
            add(x,y,z);
            add(y,x,z);
        }
        dfs(0,-1,0);
        for(int i=0;i<n;i++)
            Insert(dp[i]);
        int ans=0;
        for(int i=0;i<n;i++)
            ans=max(ans,Query(dp[i]));
        cout<<ans<<endl;
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:Trie

          本文链接:https://www.haomeiwen.com/subject/uufkkhtx.html