zoukankan      html  css  js  c++  java
  • BZOJ 1954: Pku3764 The xor-longest Path(01trie)

    求树上最长异或路径.

    根据异或的性质,我们知道a^a=0,那么a^b^b^c=a^c;

    所以我们随便找个点做根,然后dfs出每个点到根的异或路径长num[i],对于任意两点有两种情况,当根是他们的LCA时,那么两点异或路径和就直接是num[i]^num[j],不是LCA时,由于两条路径都包含了LCA到根的路径,两次异或抵消掉了,所以证得任意两点异或路径和为num[i]^num[j];

    所以把num[i]扔到trie里搞一搞就行了...

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <queue>
     7 #include <map>
     8 #define ll long long
     9 #define out(a) printf("%d",a)
    10 #define writeln printf("
    ")
    11 const int N=1e5+50;
    12 const int MOD=1e9+7;
    13 using namespace std;
    14 int n;
    15 int x,y,z;
    16 int st,tot=1,ans=-23333333;
    17 int head[N],c[N];
    18 int trie[N*31][2];
    19 bool vis[N];
    20 struct edge
    21 {
    22     int to,nxt,cost;
    23 }edge[N<<1];
    24 void add(int x,int y,int z)
    25 {
    26     edge[++tot].to=y;
    27     edge[tot].cost=z;
    28     edge[tot].nxt=head[x];
    29     head[x]=tot;
    30 }
    31 int read()
    32 {
    33     int s=0,t=1; char c;
    34     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
    35     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
    36     return s*t;
    37 }
    38 ll readl()
    39 {
    40     ll s=0,t=1; char c;
    41     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
    42     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
    43     return s*t;
    44 }
    45 void dfs(int x)
    46 {
    47     int y;
    48     for (int i=head[x];i;i=edge[i].nxt){
    49       y=edge[i].to;
    50       if (!vis[y]){
    51         vis[y]=true;
    52         c[y]=c[x]^edge[i].cost;
    53         dfs(y);
    54       }
    55     }
    56 }
    57 void insert(int x)
    58 {
    59     int u=1;
    60     for (int i=31;i>=0;i--){
    61       int c=((1<<i)&x)>0;
    62       if (!trie[u][c]) trie[u][c]=++tot;
    63       u=trie[u][c];
    64     }
    65 }
    66 int find(int x)
    67 {
    68     int u=1;
    69     int res=0;
    70     for (int i=31;i>=0;i--){
    71       int c=((1<<i)&x)>0;
    72       if (trie[u][1-c]) u=trie[u][1-c],res+=(1<<i);    
    73       else u=trie[u][c];
    74     }
    75     return res;
    76 }
    77 int main()
    78 {
    79     n=read(); memset(vis,false,sizeof(vis));
    80     for (int i=1;i<n;i++){
    81       x=read(),y=read(),z=read();
    82       add(x,y,z); add(y,x,z);
    83       if (i==1) st=x;
    84     }
    85     dfs(st);
    86     for (int i=1;i<=n;i++)
    87       if (c[i]) {
    88           ans=max(ans,c[i]);
    89         ans=max(ans,find(c[i]));
    90         insert(c[i]);
    91       }
    92     out(ans);
    93     return 0;
    94 }
    95         
    View Code
  • 相关阅读:
    CCF-Python的内置函数们
    CCF2019-03-Python题解
    Find a Number (记忆化+BFS)
    LeetCode15:三数之和(双指针)
    LeetCode:不用加号的加法(位运算)
    剑指Offer43:1~n整数中1出现的次数(数位DP)
    LeetCode190:颠倒二进制(位运算分治! 时间复杂度O(1))
    LeetCode5716:好因子的最大数目(数学、快速幂)
    python学习笔记:python的字符串拼接效率分析
    LeetCode1806:还原排列的最少操作步数(置换群 or 模拟)
  • 原文地址:https://www.cnblogs.com/Kaleidoscope233/p/9563276.html
Copyright © 2011-2022 走看看