蒟蒻的trie树专题

POJ 3630 Phone List: 模板

///meek

#include<bits/stdc++.h>
using namespace std;

using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//****************************************
const int  N=500000+50;
#define mod 10000007

#define inf 10000007
#define maxn 10000

char a[N];
struct Trie {
       int ch[N][26],sum[N];
       int siz;
       Trie() { siz=1;
                mem(ch);mem(sum);
       }
       int idx(char c) {return c-'a';}
       void insertt(char *s) {
            int u=0,n=strlen(s);
            for(int i=0;i<n;i++) {
                int c=idx(s[i]);
                if(!ch[u][c]) {
                    ch[u][c]=siz++;
                }
                u=ch[u][c];sum[u]++;
            }
       }
       int ask(char *s) {
           int u=0,n=strlen(s);
           for(int i=0;i<n;i++) {
             int c=idx(s[i]);
             if(ch[u][c]) u=ch[u][c];
             else return 0;
           }
           return sum[u];
       }
}trie;
int main() {
    while(gets(a)) {
        if(strlen(a)==0)break;
        trie.insertt(a);
    }
    while(scanf("%s",a)!=EOF) {
        cout<<trie.ask(a)<<endl;
    }
    return 0;
}
POJ3630

HDU 1004 Let the Balloon Rise:模板

///meek

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//****************************************
const int  N=1000+2;
#define mod 10000007

#define inf 10000007
#define maxn 10000


struct Trie{
    int ch[N][26],sum[N],siz=1,W=0,ansi,ans;
    void init() {mem(ch),mem(sum),siz=1;W=0,ansi=0;ans=-1;}
    int idx(char c) {return c-'a';}
    void insertt(char *s) {
        int u=0,n=strlen(s);
         W++;
        for(int i=0;i<n;i++) {
            int c=idx(s[i]);
            if(!ch[u][c]) {
                ch[u][c]=siz++;
            }
            u=ch[u][c],sum[u]++;
            if(ans<sum[u]&&i==n-1) {ans=sum[u];ansi=W;}
        }
    }
}trie;
int main() {
   char a[N][150];int n;
    while(scanf("%d",&n)&&n) {
            trie.init();
        for(int i=1;i<=n;i++) {
            scanf("%s",a[i]);
            trie.insertt(a[i]);
        }
        cout<<a[trie.ansi]<<endl;
    }
    return 0;
}
HDU1004

HDU 1251统计难题 :查找前缀个数

///meek

#include<bits/stdc++.h>
using namespace std;

using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//****************************************
const int  N=500000+50;
#define mod 10000007

#define inf 10000007
#define maxn 10000

char a[N];
struct Trie {
       int ch[N][26],sum[N];
       int siz;
       Trie() { siz=1;
                mem(ch);mem(sum);
       }
       int idx(char c) {return c-'a';}
       void insertt(char *s) {
            int u=0,n=strlen(s);
            for(int i=0;i<n;i++) {
                int c=idx(s[i]);
                if(!ch[u][c]) {
                    ch[u][c]=siz++;
                }
                u=ch[u][c];sum[u]++;
            }
       }
       int ask(char *s) {
           int u=0,n=strlen(s);
           for(int i=0;i<n;i++) {
             int c=idx(s[i]);
             if(ch[u][c]) u=ch[u][c];
             else return 0;
           }
           return sum[u];
       }
}trie;
int main() {
    while(gets(a)) {
        if(strlen(a)==0)break;
        trie.insertt(a);
    }
    while(scanf("%s",a)!=EOF) {
        cout<<trie.ask(a)<<endl;
    }
    return 0;
}
HDU1251

HDU 4825 Xor Sum : 给你n个数m个询问,每隔询问一个A,问你这n个数中与A异或值最大是多少,

                                 将树转化成01 串的trie树,经典题型

///meek

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//****************************************
const int  N=2000000+2;
#define mod 10000007

#define inf 10000007
#define maxn 10000

struct Trie{
   int ch[N][3],sum[N],siz=1,ans,W;
   void init(){mem(sum),mem(ch),siz=1;}
   void insertt(int x) {
       int tmp=x;
        int each[40],k=1;mem(each);
        while(x) {
            each[k++]=x%2;
            x/=2;
        }int u=0;
        for(int i=32;i>=1;i--) {
            int c=each[i];
            if(!ch[u][c]){
                ch[u][c]=siz++;
            }
            u=ch[u][c];if(i==1)sum[u]=tmp;
        }
   }
   int ask(int x) {
       int u=0;int tmp=x;
        int each[40],k=1;mem(each);
         while(x) {
            each[k++]=x%2;
            x/=2;
        }
        for(int i=32;i>=1;i--) {
            int g,c=each[i];if(c==1)g=0;else g=1;
            if(ch[u][g]) {
                u=ch[u][g];
            }
            else u=ch[u][c];
            if(i==1) return sum[u];
        }
   }
}trie;
int main() {

    int T=read(),n,m,z[N];
    int oo=1;
    while(T--) {int a[N];
         trie.init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
            trie.insertt(a[i]);
        }
        for(int i=1;i<=m;i++) {
            scanf("%d",&z[i]);
        } printf("Case #%d:
",oo++);
        for(int i=1;i<=m;i++) {
            cout<<trie.ask(z[i])<<endl;
        }
    }
    return 0;
}
HDU 4825

POJ 3764 The xor-longest Path: 

 题意:给你一个树,及n-1条边权,问你任意一条路径上最大异或边权值是多少

题解: 我们根据异或性质,对于u->v这条路径上异或值可以转化为 XOR(0->v)^XOR(0->u)

         我们先dfs出根节点到任意节点的路径异或值,于是转化成任意两个数的 异或最大值了

             

///meek

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }return x*f;
}
//****************************************
const int  N=2000000+200;
#define mod 10000007

#define inf 10000007
#define maxn 10000

int a[N],head[N],t,n;
struct ss {
   int to,next,va;
}e[N*2];
void init() {mem(head),t=1;}
void add(int u,int v,int w) {e[t].to=v;e[t].va=w;e[t].next=head[u];head[u]=t++;}
void dfs(int x,int pre) {
     for(int i=head[x];i;i=e[i].next) {
        if(e[i].to==pre) continue;
        a[e[i].to]=e[i].va^a[x];
        dfs(e[i].to,x);
     }
}
struct Trie{
   int ch[N][3],sum[N],siz,ans,W;
   void init(){mem(sum),mem(ch),siz=1;}
   void insertt(int x) {
       int tmp=x;
        int each[40],k=1;mem(each);
        while(x) {
            each[k++]=x%2;
            x/=2;
        }int u=0;
        for(int i=32;i>=1;i--) {
            int c=each[i];
            if(!ch[u][c]){
                ch[u][c]=siz++;
            }
            u=ch[u][c];if(i==1)sum[u]=tmp;
        }
   }
   int ask(int x) {
       int u=0;int tmp=x;
        int each[40],k=1;mem(each);
         while(x) {
            each[k++]=x%2;
            x/=2;
        }
        for(int i=32;i>=1;i--) {
            int g,c=each[i];if(c==1)g=0;else g=1;
            if(ch[u][g]) {
                u=ch[u][g];
            }
            else u=ch[u][c];
            if(i==1) return sum[u];
        }
   }
}trie;
int main() {

    while(scanf("%d",&n)!=EOF) {
        int u,v,w;init();
        trie.init();
        for(int i=1;i<n;i++) {
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w),add(v,u,w);
        }
        memset(a,0,sizeof(a));
        dfs(0,-1);
        for(int i=0;i<n;i++) {
            trie.insertt(a[i]);
        }
        int ans=0;
        for(int i=0;i<n;i++) {
            ans=max(ans,a[i]^trie.ask(a[i]));
        }
        cout<<ans<<endl;
    }
    return 0;
}
POJ 3764
原文地址:https://www.cnblogs.com/zxhl/p/4973066.html