zoukankan      html  css  js  c++  java
  • 【Trie】The XOR-longest Path

    【题目链接】:

    https://loj.ac/problem/10056

    【题意】

    请输出树上两个点的异或路径  的最大值。

    【题解】

    这个题目,y总说过怎么做之后,简直就是醍醐灌顶了。

    我们知道Xor路径,我们从根结点处理所有结点的  到根结点的异或和,我们想要两个点的异或路径。

    其实就是利用根结点  到两个点  异或和 。因为LCA到根结点异或了两遍,所以答案就保留了异或路径的部分。

    其实这个题目就是Xor——pair的变种。

    处理从根结点出发的所有结点的位置的异或值。

    【代码】

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N = 1e5 + 100 ;
     6 int Son[N*31][2];
     7 typedef struct Edge{
     8     int To , next , w ;
     9 }Edge ;
    10 Edge e[N<<1];
    11 int Head[N],cnt,Dis[N],idx;
    12 void Init(){
    13     memset( Head , -1 ,sizeof Head );
    14     cnt = idx = 0 ;
    15 }
    16 void Add_edge ( int u, int v ,int w ){
    17     e[cnt] = Edge { v , Head[u] , w };
    18     Head[u] = cnt ++ ;
    19 }
    20 
    21 void dfs(int u,int Fa,int w ){
    22     Dis[u] = w ;
    23     for(int i = Head[u] ; ~i ; i = e[i].next){
    24         int To = e[i].To;
    25         if( To == Fa ) continue ;
    26         dfs( To , u , w ^ e[i].w );
    27     }
    28 }
    29 
    30 void Insert ( int x ){
    31     int p = 0 ;
    32     for (int i=30;~i;i--){
    33         int t = x >> i & 1 ;
    34         if( !Son[p][t] )
    35             Son[p][t] = ++idx ;
    36         p = Son[p][t] ;
    37     }
    38 }
    39 int Query(int x ){
    40     int p = 0 ,res = 0;
    41     for(int i=30;~i;i--){
    42         int t = x >> i & 1 ;
    43         if( Son[p][t^1] ){
    44             res += 1 << i ;
    45             p = Son[p][t^1];
    46         }else{
    47             p = Son[p][t] ;
    48         }
    49     }
    50     return res ;
    51 }
    52 int main()
    53 {
    54     Init();
    55     int n ;
    56     scanf("%d",&n);
    57     for(int i=1,u,v,w;i<n;i++){
    58         scanf("%d%d%d",&u,&v,&w);
    59         Add_edge( u , v , w );
    60         Add_edge( v , u , w );
    61     }
    62     dfs( 1 , -1 , 0 ) ;
    63     /*
    64     for(int i=1;i<=n;i++){
    65         printf("###%d###
    ",Dis[i]);
    66     }
    67     */
    68     for(int i=1;i<=n;i++){
    69         Insert( Dis[i] );
    70     }
    71     int res = 0;
    72     for(int i=1;i<=n;i++){
    73         res = max( res , Query(Dis[i] ) );
    74     }
    75     printf("%d
    ",res) ;
    76     return 0 ;
    77 }
  • 相关阅读:
    gridview填加双击事件
    后台找前台服务器控件,客户端控件方法
    ie缓存是什么 和 清除ie缓存方法
    js 去掉空格的方法
    SQL 用户sa登录失败,该用户与可信sql server连接无关联
    (转)C#里面比较时间大小三种方法
    sql UNION 和 UNION ALL 的区别
    windows 计划任务 打开窗口
    mysql 优化8种方式
    javascript小括号表达式
  • 原文地址:https://www.cnblogs.com/Osea/p/11366907.html
Copyright © 2011-2022 走看看