AcWing 1282. 搜索关键词

给定n个长度不超过50的由小写英文字母组成的单词,以及一篇长为m的文章。

请问,有多少个单词在文章中出现了。

#include<bits/stdc++.h>
using namespace std;
const int N = 10010, S = 55, M = 1000010;
int n;
int tr[N * S][26], cnt[N * S], idx;
char s[M];
int q[N * S], ne[N * S];
void insert()
{
    int p=0;
    for(int i=0;s[i];i++)
    {
        int t=s[i]-'a';
        if(!tr[p][t])tr[p][t]=++idx;
        p=tr[p][t];
    }
    cnt[p]++;
}
void build()
{
    int hh=0,tt=-1;
    for(int i=0;i<26;i++)
        if(tr[0][i])
            q[++tt]=tr[0][i];
    while(hh<=tt)
    {
        int t=q[hh++];
        for(int i=0;i<26;i++)
        {
            int p=tr[t][i];
            if(!p)tr[t][i]=tr[ne[t]][i];
            else 
            {
                ne[p]=tr[ne[t]][i];
                q[++tt]=p;
            }
        }
    }
}    
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(tr,0,sizeof tr);
        memset(cnt,0,sizeof cnt);
        memset(ne,0,sizeof ne);
        idx=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%s",s);
            insert();
        }
        build();
        scanf("%s",s);
        int res=0;
        for(int i=0,j=0;s[i];i++)
        {
            int t=s[i]-'a';
            j=tr[j][t];
            int p=j;
            while(p)
            {
                res+=cnt[p];
                cnt[p]=0;
                p=ne[p];
            }
        }
        printf("%d\n",res);
    }
return 0;
}

 

posted @ 2021-02-05 10:23  君与  阅读(45)  评论(0编辑  收藏  举报