数据结构trie树

Posted xwww666666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构trie树相关的知识,希望对你有一定的参考价值。

一个处理字符串查找xort问题的常用工具

1>最长异或路径

给定一棵n个点的带权树,结点下标从1开始到N。寻找树中找两个结点,求最长的异或路径。

异或路径指的是指两个结点之间唯一路径上的所有边权的异或。

1n100000

0w<2^31

 

题意:
一颗最小生成树,带边权
求 所有路径中,边权异或后得到的值,最大是多少

1)最小生成树,那就先拎出来一个顶点

2)从顶点,分出一条条独立的路径

3)这些路径的起点都是rt,所以每条路径的异或结果都容易记录,记为xo[i](rt->i)

 

4)尝试将以rt为起点的路径,与其他路径的异或结果建立关系,发现xo(i->j)=xo(rt->i)^xo(rt->j) (rt,i,j的关系任意)

5)肯定不会去枚举,那么我们把xo(rt->i)的值,按照高位到低位的顺序,放在字母树上

6)然后用xo(rt->i)去找,每次找最大值

7)一个ans记录每次的最大值,中的最大值

8)输出ans

#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;
int n;
const int N=100003;
struct node

    int v,w;
    node(int vv,int ww)
     v=vv,w=ww; 
    node()
;
vector <node > g[N];

int xo[N];
void dfs(int nw,int pre)

    int sz=g[nw].size() ;
    for(int i=0;i<sz;i++)
    
        node t=g[nw][i];
        if(t.v ==pre) continue;
        
        xo[t.v ]=xo[nw]^t.w ;
        dfs(t.v ,nw );
    


int rt;
int trie[N*31][2],cnt;
void build(int x)

    int pos=rt;
    for(int i=1<<30;i;i>>=1)
    
        bool tt=i&x;
        if(!trie[pos][tt]) trie[pos][tt]=++cnt;
        pos=trie[pos][tt];
    


int ans;
int query(int x)

    int pos=rt,as=0;
    for(int i=1<<30;i;i>>=1)
    
        bool tt=x&i;
        if(trie[pos][tt^1]) pos=trie[pos][tt^1],as+=i;
        else pos=trie[pos][tt];
    
    return as;


int main()

    scanf("%d",&n);
    for(int i=1,u,v,w;i<n;i++)
        scanf("%d%d%d",&u,&v,&w),
        g[u].push_back(node(v,w)),g[v].push_back(node(u,w)); 
    
    dfs(1,0);
    for(int i=1;i<=n;i++) build(xo[i]);
    
    for(int i=1;i<=n;i++) 
        ans=max(ans,query(xo[i]));
    printf("%d\n",ans);
    
    return 0;

 

以上是关于数据结构trie树的主要内容,如果未能解决你的问题,请参考以下文章

高级数据结构(Ⅴ)单词查找树(Trie)

字典树208. 实现 Trie (前缀树)

算法与数据结构Trie树简介及应用

大数据处理-Trie树

LeetCode 208. 实现 Trie (前缀树)

数据结构~trie树(字典树)