题意:
给一个含n个串的字典
m次询问,每次询问给出一个字符串
问字典中是否存在一个串,满足该串与询问串恰好有一个字符不同
所有串只包含a、b、c
数据范围:n,m<=3e5
解法:
解法1:
将给定字典的每个串哈希一下,存下哈希值然后排序
枚举询问串的修改位置和修改字符,然后二分判断字典中是否存在修改之后的串
复杂度O(Llog(n)),其中L是询问串的长度
但是这题一些简单的哈希好像会被卡,要用双哈希之类的操作才能过
解法2:
对给定字典建立字典树,用询问串在字典树上dfs即可,修改字符即走与原串不同的路径
因为必须要有一个字符不同,可以开一个flag标记记录是否修改过字符
代码是解法2
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=6e5+5;
int ok;
struct Trie{
int a[maxm*3][3],tot;
int is[maxm*3];
void add(char* s){
int node=0;
int len=strlen(s);
for(int i=0;i<len;i++){
int v=s[i]-'a';
if(!a[node][v])a[node][v]=++tot;
node=a[node][v];
}
is[node]=1;
}
void dfs(int node,char* s,int cur,int len,int f){
if(ok)return ;
if(cur==len){
if(f&&is[node])ok=1;
return ;
}
int v=s[cur]-'a';
for(int i=0;i<3;i++){
if(a[node][i]){
if(i==v)dfs(a[node][i],s,cur+1,len,f);
else if(!f){
dfs(a[node][i],s,cur+1,len,1);
}
}
}
}
}T;
int n,m;
char s[maxm];
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",s);
T.add(s);
}
for(int i=1;i<=m;i++){
scanf("%s",s);
int len=strlen(s);
ok=0;
T.dfs(0,s,0,len,0);
if(ok)puts("YES");
else puts("NO");
}
return 0;
}