【AC自动机】洛谷P3796 AC自动机(加强版)

链接

https://www.luogu.org/problemnew/show/P3796


大意

给定 n n 个串和一个文本串,找出所有在文本串中出现次数最多的串(可能有多个),并输出出现的次数


思路

AC A C 自动机,更改一下查找的部分即可


代码

#include
#include
#include
#define zero(x) memset(x,0,sizeof(x))
using namespace std;char s[151][71],T[1000010];
queue<int>q;
int nxt[1000010],trie[1000010][26],num[1000010],tot,n,ans[1000010];
inline void build()//构造失配指针
{
    for(register int i=0;i<26;i++) if(trie[0][i]) nxt[trie[0][i]]=0,q.push(trie[0][i]);
    while(q.size())
    {
        int x=q.front();q.pop();
        for(register int i=0;i<26;i++)
        if(trie[x][i]) nxt[trie[x][i]]=trie[nxt[x]][i],q.push(trie[x][i]);
        else trie[x][i]=trie[nxt[x]][i];
    }
}
inline void insert(char* s,register int id)//插入s
{
    int len=strlen(s),p=0;
    for(register int i=0;iint ch=s[i]-'a';
        if(!trie[p][ch]) trie[p][ch]=++tot;
        p=trie[p][ch];
    }
    num[p]=id;
}
inline void query(char *b)//查询
{
    int len=strlen(b),p=0,maxn=0;
    for(register int i=0;i'a'];
        if(num[p]) ans[num[p]]++;
        for(register int t=nxt[p];t;t=nxt[t]) if(num[t]) ans[num[t]]++;//统计答案
    }
    for(register int i=1;i<=n;i++) maxn=max(ans[i],maxn);//找出最多出现次数
    printf("%d\n",maxn);//输出
    for(register int i=1;i<=n;i++) if(ans[i]==maxn) puts(s[i]);//输出
    return;
}
signed main()
{
    while(scanf("%d",&n),n)
    {
        zero(nxt);zero(trie);zero(num);zero(ans);tot=0;
        for(register int i=1;i<=n;i++) scanf("%s",s[i]),insert(s[i],i);
        build();
        scanf("%s",T);
        query(T);
    }
}

你可能感兴趣的:(Trie,AC自动机,KMP)