题意:

先给n个字符串(由a,b,c组成),再给m个查询,问存不存在和n个中的某一个只差一个字符
(0 ≤ n ≤ 3·10, 0 ≤ m ≤ 3·10)

题解:

n和m都很大
有两种做法:hash和字典树
就是很暴力的做法
把模板串整体哈希并记录值
图片说明
然后依次改变目标串的每一位,改成a~c,然后查看是否存储过,没有就移动到下一位进行相同的操作

字典树
利用字典树处理前n个字符串,然后再字典树上跑dfs

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=6e5+9;
ll p[maxn];
set<ll>myset;
ll mod=1e12+7;
int main()
{
    p[0]=1;
    for(int i=1;i<=maxn;i++)
    {
        p[i]=(p[i-1]*131)%mod;
    }
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        string s;
        cin>>s;
        ll sum=0;
        int len=s.length();
        for(int j=0;j<=len-1;j++)
        {
            sum=(sum*131+s[j]-'0')%mod;
        }
        myset.insert(sum);
    }
    for(int i=1;i<=m;i++)
    {
        string s;
        cin>>s;
        ll sum=0;
        ll ans=0;
        bool f=0;
        int len=s.length();
        for(int j=0;j<=len-1;j++)
        {
            sum=(sum*131+s[j]-'0')%mod;
        }
        for(int j=0;j<=len-1;j++)
        {
            if(f==1)break;    
            for(char x='a';x<='c';x++)
            {
                if(s[j]==x)continue;
                ans=(sum-(s[j]-'0')*p[len-j-1])%mod;
                if(ans<0)ans=(ans+mod)%mod;
                ans=(ans+(x-'0')*p[len-j-1])%mod;
                if(myset.count(ans))
                {
                    f=1;
                    break;
                }
            }


        }
        if(f)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;

    }
    return 0;
}

字典树

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <map>
#include <set>
#define LL long long
using namespace std;
#define maxn 300007
#define maxx 600007
#define maxNode 3
int num[maxn][3];
char s[maxx];
struct node
{
    node* next[maxNode];
    int flag;
};

node* createNode()
{
    node *q=new node;
    for(int i=0;i<maxNode;i++)
    {
        q->next[i]=NULL;
    }
    return q;
}
void insertNode(node *trie,char *c)
{
    int i=0;
    int k;
    node *p=trie;
    while(c[i])
    {
        k=c[i++]-'a';
        if(p->next[k]==NULL)
        {
            node *q=createNode();
            p->next[k]=q;
        }
        p=p->next[k];
    }
    p->flag=1;
}

int dfs(node *trie,char *c,int x)
{
    node *p=trie;
    int i,j;
    if(trie==NULL) return 0;
    if(c[0]=='\0')
    {
        if(x==1&&p->flag)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    for(i=0;i<3;i++)
    {
        if(c[0]=='a'+i)
        {
            if(dfs(trie->next[i],c+1,x)) return 1;
        }
        else if(x==0)
        {
            if(dfs(trie->next[i],c+1,1)) return 1;
        }
    }
    return 0;
}
int main()
{
    int len,n,i,j,k,m,x,y;
    scanf("%d%d",&n,&m);
    node *trie=createNode();
    for(i=1;i<=n;i++)
    {
        scanf("%s",s);
        insertNode(trie,s);
    }
    for(j=1;j<=m;j++)
    {
        scanf("%s",s);
        bool flag=0;
        for(i=0;i<3;i++)
        {
            if(s[0]=='a'+i)
            {
                if(dfs(trie->next[i],s+1,0))
                {
                    flag=1;
                    break;
                }
            }
            else if(dfs(trie->next[i],s+1,1))
            {
                flag=1;
                break;
            }
        }
        if(flag) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}