• 【维护异或极值】 最长异或路径


    传送门

    题意

    给定一棵树,树上的边都有权值,树上的一条异或路径长度定义为两点间路径上所有边的异或和

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

    给定上述的具有(n)个节点的树,求最大的异或和路径的值

    数据范围

    (egin{array}{l}1 leq n leq 100000 \ 0 leq u, v<n \ 0 leq w<2^{31}end{array})

    题解

    • 维护每个节点从根到它路径的异或和,求任意两点的路径直接异或两个点到根的异或和即可

      • (dfs)求出每个节点到根的异或和,三个状态当前节点、上一节点、当前异或和

      • 树是无向的,所以要判断一下下一个点是不是等于上一个点

    • 异或运算的计算顺序不影响结果

    • 如果两个节点从(LCA)开始的公共路径的异或值相同,异或和为(0),相当于不异或

    所以求任意两点间就用字典树维护所有点到根的距离,贪心的从高位开始选择,优先选择高位不同的,
    即高位异或后可以得到的值

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define per(i,a,n) for(int i=n-1;i>=a;i--)
    
    const int N=1e5+10;
    
    int n;
    
    struct node
    {
        int to,ne,w;
    }e[N*2];
    int h[N],id;
    int d[N];
    int trie[N*30][2],tot=1;
    void add(int u,int v,int w)
    {
        e[++id].to = v;
        e[id].w=w;
        e[id].ne=h[u];
        h[u]=id;
    }
    void insert(int x)
    {
        int p=1;
        per(i,0,31)
        {
            int c = x>>i&1;
            if(!trie[p][c]) trie[p][c]=++tot;
            p=trie[p][c];
        }
    }
    int query(int x)
    {
        int res=0;
        int p=1;
        per(i,0,31)
        {
            int c=x>>i&1;
            if(trie[p][!c])
            {
                res+=1<<i;
                p=trie[p][!c];
            }
            else p=trie[p][c];
        }
        return res;
    }
    void dfs(int u,int pre,int sum)
    {
        d[u]=sum; 
        for(int i=h[u];i;i=e[i].ne)
            if(e[i].to!=pre) dfs(e[i].to,u,sum^e[i].w);
    }
    
    void solve()
    {
        int ans=-1e9;
        cin>>n;
        rep(i,0,n)
        {
            int u,v,w;
            cin>>u>>v>>w;
            add(u,v,w);add(v,u,w);
        }
        dfs(0,-1,0);
    
        rep(i,0,n)
        {
            insert(d[i]);
            ans=max(ans,query(d[i]));
        }
        cout<<ans<<endl;
    }
    int main()
    {
        solve();
        return 0;
    }
    
  • 相关阅读:
    kill all process on a specific port on linux 码农
    rxjs 学习系列二(环境搭建) 码农
    实拍图与摄相头自动合成软件(效果) 码农
    js中for in的用法
    Android sdk资源包res里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)
    js中addEventListener中第3个参数
    【agc006f】Blackout
    Trie&可持久化Trie
    【agc014d】Black and White Tree
    【agc009b】Tournament
  • 原文地址:https://www.cnblogs.com/hhyx/p/13394296.html
Copyright © 2020-2023  润新知