AC自动机模板2

题目链接:https://www.luogu.org/problemnew/show/P3796

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
using namespace std;
#define ll long long
#define re register
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define P pair<int,int>
const int N=1e6+10;
const int mod=1e9+7;
void read(int &a)
{
    a=0;
    int d=1;
    char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch-'0';
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=a*10+ch-'0';
    a*=d;
}
void write(int x)
{
    if(x<0)
        putchar(45),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
struct note
{
    int next;
    int to[30];
    int bz;
}trie[N];
int tot;
struct node
{
    int sum,pos;
}ans[151];
bool cmp(node x,node y)
{
    if(x.sum!=y.sum)
        return x.sum>y.sum;
    else
        return x.pos<y.pos;
}
string s[151];
inline void clean(int x)
{
    trie[x].next=0;
    trie[x].bz=0;
    memset(trie[x].to,0,sizeof(trie[x].to));
}
inline void ins(string s,int k)
{
    int len=s.length();
    int now=0;
    for(re int i=0;i<len;i++)
    {
        int x=s[i]-96;
        if(!trie[now].to[x])
            trie[now].to[x]=++tot,clean(tot);
        now=trie[now].to[x];
    }
    trie[now].bz=k;
}
inline void built()
{
    queue <int> q;
    for(re int i=1;i<=26;i++)
        if(trie[0].to[i])
            trie[trie[0].to[i]].next=0,q.push(trie[0].to[i]);
    while(!q.empty())
    {
        int p=q.front();
        q.pop();
        for(re int i=1;i<=26;i++)
        {
            if(trie[p].to[i])
                trie[trie[p].to[i]].next=trie[trie[p].next].to[i],q.push(trie[p].to[i]);
            else
                trie[p].to[i]=trie[trie[p].next].to[i];
        }
    }
}
inline void solve(string s)
{
    int len=s.length();
    int now=0;
    for(re int i=0;i<len;i++)
    {
        int x=s[i]-96;
        now=trie[now].to[x];
        for(re int t=now;t;t=trie[t].next)
            ans[trie[t].bz].sum++;
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        tot=0;
        clean(0);
        for(re int i=1;i<=n;i++)
        {
            cin>>s[i];
            ans[i].sum=0;
            ans[i].pos=i;
            ins(s[i],i);
        }
        trie[0].next=0;
        built();
        cin>>s[0];
        solve(s[0]);
        sort(ans+1,ans+1+n,cmp);
        cout<<ans[1].sum<<endl;
        cout<<s[ans[1].pos]<<endl;
        for(re int i=2;i<=n;i++)
        {
            if(ans[i].sum==ans[i-1].sum)
                cout<<s[ans[i].pos]<<endl;
            else
                break;
        }
    }
    return 0;
}