[模板] Trie 树
听机房人说这是个特别简单的数据结构
于是他错误的点名开始了
\(Trie\) 树一般有两种操作(具体问题具体修改):
定义
-
定义一个类似于邻接表的东西和初始节点
-
其中 \(t\) 数组第二维表示 \(c\) 字符在当前节点指向的节点编号
int trie[maxn][26],cnt=1;
\(maxn\) 表示最长字符长度*字符个数
插入
void insert(char *s){
int len=strlen(s),p=1;
for(int k=0;k<len;k++){
int ch=s[k]-'a';
if(!trie[p][ch])trie[p][ch]=++cnt;//开点
p=trie[p][ch];
}
end[p]=true;//记录每个位置是不是字符串的结尾,非常有必要
}
查询是否存在
bool find(char *s){
int len=strlen(s),p=1;
for(int k=0;k<len;k++){
p=trie[p][s[k]-'a'];
if(!p)return false;
}
return end[p];//end的用处
}
题解
对于此题而言,稍加修改即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
template <typename T>
inline T read(){
T x=0;char ch=getchar();bool fl=false;
while(!isdigit(ch)){if(ch=='-')fl=true;ch=getchar();}
while(isdigit(ch)){
x=(x<<3)+(x<<1)+(ch^48);ch=getchar();
}
return fl?-x:x;
}
const int maxn = 5e5 + 100;
int n,m;
#define LL long long
int t[maxn][26],cnt=1;
bool end[maxn],vis[maxn];
void insert(char *s){
int len=strlen(s),p=1;
for(int k=0;k<len;k++){
int ch=s[k]-'a';
if(!t[p][ch])t[p][ch]=++cnt;
p=t[p][ch];
}
end[p]=true;
}
int search(char *s){
int len=strlen(s),p=1;
for(int k=0;k<len;k++){
p=t[p][s[k]-'a'];
if(!p)return 0;
}
if(!end[p])return 0;
else{
if(!vis[p]){vis[p]=true;return 1;}
else if(vis[p])return 2;
}
}
int main(){
n=read<int>();
while(n--){
char ch[55];cin>>ch;
insert(ch);
}
m=read<int>();
while(m--){
char ch[55];cin>>ch;
int fl=search(ch);
if(fl==0)puts("WRONG");
else if(fl==1)puts("OK");
else puts("REPEAT");
}
return 0;
}