Trie树(又叫前缀树或字典树)是一种树形结构,专门用于高效地存储和查找字符串集合,特别适合处理前缀相关问题,如自动补全、字符串匹配、前缀计数等。
代码模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
   | 
  int son[N][N],cnt[N],idx;
 
 
 
 
  void insert(const char *str) {     int p=0;     for(int i=0;str[i];i++)     {         int u=str[i]-'a';         if(!son[p][u])son[p][u]=++idx;         p=son[p][u];     }     cnt[p]++; }
  int query(const char *str) {     int p=0;     for(int i=0;str[i];i++)     {         int u=str[i]-'a';         if(!son[p][u])return 0;         p=son[p][u];     }     return cnt[p]; }
 
  | 
 
一道经典题目:最大异或数
在给定的 N 个整数 A1,A2……AN 中选出两个进行 xor(异或)运算,得到的结果最大是多少?
输入格式
第一行输入一个整数 N。
第二行输入 N 个整数 A1~AN。
输出格式
输出一个整数表示答案。
数据范围
1≤N≤105,
0≤Ai<231
分析:很明显,需要把每一个整数拆成32位,然后逐步插入Trie树(这里就只有0和1两种了),所有处理完之后,我们对每一个数去找可能最大的异或数,然后取所有的最大值就好了。
具体如果找异或数呢,其实也就是遍历数的过程,如果有跟当前位相反的,就直接取,否则就只能取0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
   | #include<iostream> #include<vector> using namespace std; const int N=32*1e5+10; int son[N][2],idx; void insert(int x) {     int p=0;     for(int i=31;i>=0;i--)     {         int bit=(x>>i)&1;         if(!son[p][bit])son[p][bit]=++idx;         p=son[p][bit];     } } int main() {     int n;scanf("%d",&n);     vector<int>nums;     for(int i=0;i<n;i++){         int x;scanf("%d",&x);         insert(x);nums.push_back(x);     }     int ans=0;     for(int x:nums)     {         int sum=0;int p=0;         for(int i=31;i>=0;i--)         {             int bit=(x>>i)&1;             int op=bit^1;             if(son[p][op])             {                 sum|=(1<<i);                 p=son[p][op];             }             else p=son[p][bit];         }         ans=max(ans,sum);     }     printf("%d",ans); }
   |