zoukankan      html  css  js  c++  java
  • 题解 bzoj1954【Pku3764 The xor – longest Path】

    做该题之前,至少要先会做这道题


    (d[u]) 表示 (1)(u) 简单路径的异或和,该数组可以通过一次遍历求得。

    (~)

    考虑 (u)(v) 简单路径的异或和该怎么求?

    (z=operatorname{lca}(u,v)) ,则 (u)(v) 简单路径的异或和可以分成两段求解:一段是 (z)(u) 简单路径的异或和,一段是 (z)(v) 简单路径的异或和,二者异或一下即为 (u)(v) 简单路径的异或和。

    由于异或 "(a operatorname{xor} a=0)" 的性质,两条路径重叠的部分异或起来即为 (0),可得

    (z)(v) 简单路径的异或和为

    [d[u] operatorname{xor} d[z] ]

    (z)(v) 简单路径的异或和为

    [d[v] operatorname{xor} d[z] ]

    进一步,可得

    (u)(v) 简单路径的异或和为

    [(d[u]operatorname{xor}d[z])operatorname{xor}(d[v]operatorname{xor}d[z]) ]

    ​ 由于异或满足交换律,可化简为

    [d[u]operatorname{xor}d[v] ]

    由上述性质,答案即为 (maxlimits_{1leq i<jleq n})({d[i] operatorname{xor} d[j]}),又回到了这道题,字典树直接解决即可。

    时间复杂度 ( heta(32n))


    CODE

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    
    #define RI register int
    
    using namespace std;
    
    inline int read()
    {
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10-'0'+s;s=getchar();}
        return x*f;
    }
    
    const int N=100100,M=200100;
    
    int n;
    int tot_E,head[N],ver[M],edge[M],Next[M];
    
    void add(int u,int v,int w)
    {
        ver[++tot_E]=v;    edge[tot_E]=w;    Next[tot_E]=head[u];    head[u]=tot_E;
    }
    
    int d[N];
    int vis[N];
    
    void bfs()
    {
        queue<int>q;
        q.push(1);vis[1]=1;
        while(q.size())
        {
            int u=q.front();q.pop();
            for(RI i=head[u];i;i=Next[i])
            {
                int v=ver[i],w=edge[i];
                if(vis[v])continue;
                vis[v]=1;
                d[v]=d[u]^w;
                q.push(v);
            }
        }
    } 
    
    int trie[N*32+10][2],tot=1;
    int ans;
    
    void insert(int num)
    {
        int p=1;
        for(RI k=31;k>=0;k--)
        {
            int ch=num>>k&1;
            if(trie[p][ch]==0)trie[p][ch]=++tot;
            p=trie[p][ch];
        }
    }
    
    int search(int num)
    {
        int p=1,sum=0;
        for(RI k=31;k>=0;k--)
        {
            int ch=num>>k&1;
            if(trie[p][ch^1])p=trie[p][ch^1],sum+=1<<k;
            else p=trie[p][ch];
            if(p==0)return sum;
        }
        return sum;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(RI i=1;i<n;i++)
        {
            int u=read(),v=read(),w=read();
            add(u,v,w),add(v,u,w);
        }
    
        bfs();
    
        for(RI i=1;i<=n;i++)
        {
            ans=max(ans,search(d[i]));
            insert(d[i]);
        }
    
        printf("%d
    ",ans);
    
        return 0;
    }
    

    thanks for watching

  • 相关阅读:
    运算符、流程控制
    python数据类型
    Python入门基础
    pandas教程1:pandas数据结构入门
    使用matplotlib绘制多轴图
    使用matplotlib快速绘图
    浙江省新高中信息技术教材,将围绕Python进行并增加编程相关知识点
    [转]ubuntu搭建LAMP环境
    [转]字体精简
    [转]安装PIL时注册表中找不到python2.7
  • 原文地址:https://www.cnblogs.com/cjtcalc/p/12216628.html
Copyright © 2011-2022 走看看