• POJ3764 The xor-longest Path(字典树)


    题意

    给你一棵树,n个节点,n-1条边每条边i都有一个权值wi。定义任意两点间的权值为:这两点间的路径上的所有边的值的异或。比如a点和b点间有i,j,k三条边,那么ab两点间的权值为:wi^wj^wk。求这个最大的权值(最长异或路径)。

    (n<=105)

    题解

    首先  边权可以放到点权上

    然后我们可以搞一个树上的前缀异或和.
    这样的话 把当前点的所有点权加到trie树里
    从最高位到最低位走不同的路
    例:1011100101
    我们要走:0100011010
    如果走不了就顺着走
    跑出来的数异或当前的数就是经过这个点的最优解了

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const long long N=201000;
     8 long long ans,tot,cnt,head[N],n,mx,flag;
     9 struct edge{
    10     long long to,nxt,w;
    11 }e[N*2];
    12 struct tree{
    13     long long nxt[4];
    14 }tr[N*50];
    15 void insert(long long a){
    16     long long now=0,z;
    17     for(long long i=31;i>=1;i--){
    18         if(a&(1<<(i-1)))z=1;
    19         else z=0;
    20         if(!tr[now].nxt[z]){
    21             tr[now].nxt[z]=++tot;
    22             memset(tr[tot].nxt,0,sizeof(tr[tot].nxt));
    23         }
    24         now=tr[now].nxt[z];
    25     }
    26 }
    27 void check(long long x){
    28     long long tmp=0;
    29     long long now=0,z;
    30     for(long long i=31;i>=1;i--){
    31         if(x&(1<<(i-1)))z=1;
    32         else z=0;
    33         if(tr[now].nxt[!z]){
    34             tmp=(tmp<<1)+1;
    35             now=tr[now].nxt[!z];
    36         }
    37         else{
    38             tmp=tmp<<1;
    39             now=tr[now].nxt[z];
    40         }
    41     }
    42     ans=max(ans,tmp);
    43 }
    44 void add(long long u,long long v,long long w){
    45     cnt++;
    46     e[cnt].nxt=head[u];
    47     e[cnt].to=v;
    48     e[cnt].w=w;
    49     head[u]=cnt;
    50 }
    51 void dfs1(long long u,long long f,long long w){
    52     insert(w);
    53     for(long long i=head[u];i;i=e[i].nxt){
    54         long long v=e[i].to;
    55         if(v==f)continue;
    56         w^=e[i].w;
    57         dfs1(v,u,w);
    58         w^=e[i].w;
    59     }
    60 }
    61 void dfs2(long long u,long long f,long long w){
    62     check(w);
    63     for(long long i=head[u];i;i=e[i].nxt){
    64         long long v=e[i].to;
    65         if(v==f)continue;
    66         w^=e[i].w;
    67         dfs2(v,u,w);
    68         w^=e[i].w;
    69     }
    70 }
    71 int main(){
    72     while(~scanf("%lld",&n)){
    73         ans=0;cnt=0;tot=0;mx=0;flag=0;
    74         memset(head,0,sizeof(head));
    75         memset(tr[0].nxt,0,sizeof(tr[0].nxt));
    76         for(long long i=1;i<=n-1;i++){
    77             long long u,v,w;
    78             scanf("%lld%lld%lld",&u,&v,&w);
    79             u++;v++;
    80             add(u,v,w);
    81             add(v,u,w);
    82         }
    83         insert(0);
    84         dfs1(1,0,0);
    85         dfs2(1,0,0);
    86         printf("%lld
    ",ans);
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 833 字符串中的查找与替换(暴力模拟)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 832 翻转图像(位运算)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    Java实现 LeetCode 831 隐藏个人信息(暴力)
    how to use automapper in c#, from cf~
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9559154.html
Copyright © 2020-2023  润新知