字典树模板
字典树模板
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
inline int read();
int next_[500000][26];//p[节点的数量][当前节点的分支数量]
int f[500000];//表示是否以当前节点结尾
char s[30];//词组
int cnt=0;//节点的个数
void insert_(int len,int n){//插入当前单词
int now=0;//当前位置
for(int i=1;i<=len;i++){
int x = s[i] - 'a';
if(!next_[now][x]){//当前字母没有出现过就加上它
next_[now][x]=++cnt;
}
now = next_[now][x];//更新当前节点位置
}
f[now]++;//以当前节点结尾的单词数量加一
}
bool search_(int len,int n){//查找当前单词
int now=0;
for(int i=1;i<=len;i++){
int x = s[i] - 'a';
if(!next_[now][x]){
return false;//没找到某个字母返回false
}
now = next_[now][x];
}
if(f[now]!=0){//当前节点被标记为单词结尾返回true
return true;
}
else return false;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
int len=strlen(s+1);
insert_(len,i);//插入单词
}
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%s",s+1);
int len=strlen(s+1);
if(search_(len,n)){//search单词
printf("存在当前单词\n");
}
else {
printf("不存在当前单词\n");
}
}
return 0;
}
例2(求解一个字符串它的前缀字符串有多少个以及以它为前缀的字符串有多少个)
Secret Message G
思路:分两步走
1.当找到当前字符串的最后一个字母还没有找到这个字符串结尾(即当前字符串比字典树里有的字符串还要长),直接求解它前面有多少个前缀就可以了
2.当这个字符串最后一位小于字典树的最大长度,我们求出它前面的字符串的和减去以当前位置结尾的字符串的个数加上后面的以当前字符串为前缀的字符串个数就可以了 ans-f[now]+c[now]
#include<bits/stdc++.h>
using namespace std;
int next_[500010][2];
int c[500010];//有多少个单词经过当前字母
int f[500010];//统计以当前字母结尾的单词个数
int p[500010];
int cnt=0;
inline int read(){
int 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<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
void insert_(){
int n;
scanf("%d",&n);
int now=0;
int tot=1;
int flag=0;
for(int i=1;i<=n;i++){
int x= read();
if(!next_[now][x]){
next_[now][x]=++cnt;
}
now = next_[now][x];
c[now]++;
}
f[now]++;
}
int search_(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
p[i]=read();
}
int ans = 0;
int now=0;
for(int i=1;i<=n;i++){
int x = p[i];
if(!next_[now][x]){
return ans;//第一步
}
now = next_[now][x];
ans += f[now];
}
return ans-f[now]+c[now];//第二步
}
int main(){
int m = read(),n = read();
for(int i=1;i<=m;i++){
insert_();
}
for(int i=1;i<=n;i++){
int res = search_();
printf("%d\n",res);
}
return 0;
}