最长异或路径(01trie+最大异或对)

最长异或路径

板子题,但是如果把边权改成了点权的话好像就不好做了,暂时还没想好

题意:给定一棵带边权的树,求最大的异或路径。

思路

  1. 令每个节点的权值为从根到当前节点的路径上边权异或值,则此问题就被转化为普通的最大异或对了
  2. 最大异或对就没啥说的了,按顺序(随便什么顺序)把每个点加入 01 t r i e 01trie 01trie中,然后在每加入一个点前先判定当前点能与 01 t r i e 01trie 01trie中异或的最大值(贪心得搞一下就行了),把所有求出的最大值再取一个最大值就是答案了

题面描述

#include "bits/stdc++.h"
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)< pr;
inline int read() {int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}

const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-7;

int N;
int head[maxn], nxt[maxn*2], to[maxn*2], w[maxn*2], tot;
int a[maxn];
int node[maxn<<5][2], cnt;

inline void add_edge(int u, int v, int w) {
    ++tot, to[tot]=v, nxt[tot]=head[u], ::w[tot]=w, head[u]=tot;
    ++tot, to[tot]=u, nxt[tot]=head[v], ::w[tot]=w, head[v]=tot;
}

inline void max(int &a, int b) { if(a=0; --i) {
        int s=p>>i&1;
        if(!node[now][s]) node[now][s]=++cnt;
        now=node[now][s];
    }
}

inline int match(int p) {
    int now=0, ans=0;
    for(int i=30; i>=0; --i) {
        int s=p>>i&1;
        if(node[now][!s]) ans|=1<

你可能感兴趣的:(01Trie,最长异或路径,01trie,最大异或对)