【Trie树】
【Trie树/字典树/前缀树】
模版代码
【基础封装】
//注意使用时不要把空间开到栈里:开到全局变量 否则会RE
//若多组测试用例:记得trie.Clear()
struct Trie{
int ch[N][70],cnt[N],idx=0;
map<char,int> mp;
Trie(){
i64 id=0;
for(char c='a';c<='z';c++) mp[c]=++id;
for(char c='A';c<='Z';c++) mp[c]=++id;
for(char c='0';c<='9';c++) mp[c]=++id;
}
void insert(string s){
int u=0;
for(int i=0;i<s.size();i++){
int v=mp[s[i]];
if(!ch[u][v]) ch[u][v]=++idx;
u=ch[u][v];
cnt[u]++; //放里面是前缀树
}
//cnt[u]++; //放外面是字典树
}
i64 query(string s){
int u=0;
for(int i=0;i<s.size();i++){
int v=mp[s[i]];
if(!ch[u][v]) return 0;
u=ch[u][v];
}
return cnt[u];
}
void Clear(){
for(int i=0;i<=idx;i++){
cnt[i]=0;
for(int j=0;j<=62;j++){
ch[i][j]=0;
}
}
idx=0;
}
}trie;
【01字典树】
struct Trie{
int n,idx;
vector<vector<int>> ch;
void init(int n){
this->n=n;
idx=0;
ch.resize(64*(n+1),vector<int>(2));
}
void insert(int x){
int u=0;
for(int i=63;~i;i--){
int &v=ch[u][(x>>i)&1LL];
if(!v) v=++idx;
u=v;
}
}
int query(int x){
int u=0;
i64 res=0;
for(int i=63;~i;i--){
int v=(x>>i)&1LL;
if(ch[u][!v]){
res+=(1LL<<i);
u=ch[u][!v];
}
else{
u=ch[u][v];
}
}
return res;
}
}trie;
【模版题】
https://www.luogu.com.cn/problem/P8306
https://www.luogu.com.cn/problem/P10471
Trie树 字符串【模版】
题目来源:https://www.acwing.com/problem/content/837/
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
//记录儿子
int son[N][26],cnt[N],idx=0;
char str[N];
void insert(char a[]){
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(char a[]){
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];
}
int main(){
cin>>n;
while(n--){
char a[2];
scanf("%s%s",a,str);
if(a[0]=='I') insert(str);
else if(a[0]=='Q') cout<<query(str)<<'\n';
}
return 0;
}
最大异或对【Trie树应用】
题目来源:https://www.acwing.com/problem/content/145/
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
const int M=32*N;//一个数最多32位
int n;
int a[N];
int son[M][2],idx=0;
void insert(int x){
int p=0;
for(int i=30;i>=0;i--){
int u=x>>i&1;
if(!son[p][u]) son[p][u]=++idx;
p=son[p][u];
}
}
int query(int x){
int p=0,res=0;
for(int i=30;i>=0;i--){
int u=x>>i&1;
if(son[p][!u]){
p=son[p][!u];
res=res*2+1;//异或成功 +1
}
else{
p=son[p][u];
res=res*2+0;//异或不成功
}
}
return res;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
insert(a[i]);
}
int res=0;
for(int i=0;i<n;i++){
int t=query(a[i]);
res=max(res,t);
}
printf("%d",res);
return 0;
}