給定,先給出個文本串,再有個查詢串,對每個查詢串詢問:是否存在一個文本串,和查詢串恰有一個字符不同。
字符串總長不超過.
hash練手.
採取hash定位+手動複查的方式,跑了1300ms/3000ms.
如果單哈希不復查,會wa.
一個可能的優化是,按長度給字符串分組,碰撞上會好一些。
- hash過程括號錯位wa了一次
/* LittleFall : Hello! */
#include <bits/stdc++.h>
using namespace std; using ll = long long; inline int read();
const int M = 300016, MOD = 1000000007;
string tex[M], pat;
set<pair<int,int>> st; //hash_value, id
int hasher(string &str)
{
ll val = 0;
for(int i=0; str[i]; ++i)
val = (val*3+str[i]-'a')%MOD;
return val;
}
bool check(string &a, string &b)
{
if(a.size()!=b.size()) return 0;
int diff = 0;
for(int i=0; i<(int)a.size(); ++i)
if(a[i]!=b[i]) ++diff;
return diff==1;
}
ll p3[M];
int main(void)
{
#ifdef _LITTLEFALL_
freopen("in.txt","r",stdin);
#endif
p3[0] = 1;
for(int i=1; i<M; ++i)
p3[i] = p3[i-1]*3 % MOD;
int n = read(), m = read();
for(int i=1; i<=n; ++i)
{
cin >> tex[i];
int val = hasher(tex[i]);
st.insert({val, i});
}
for(int i=1; i<=m; ++i)
{
cin >> pat;
int base_val = hasher(pat);
int suc = 0;
for(int j=0; j<(int)pat.size(); ++j)
{
for(int c='a'; c<='c'; ++c) if(c!=pat[j])
{
ll nval = base_val + p3[pat.size()-1-j]*(c-pat[j]);
nval = (nval%MOD+MOD)%MOD;
auto it = st.lower_bound({nval,0});
while(it!=st.end() && it->first==nval)
{
if(check(pat, tex[it->second]))
{
suc = 1;
goto breaker;
}
++it;
}
}
}
breaker:
printf("%s\n",suc?"YES":"NO" );
}
return 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*10+ch-'0';ch=getchar();}
return x*f;
}