3172

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string.h>

using namespace std;
struct trie
{
    int next[5000010][30],fail[5000010],end[5000010];
    int root,L;
    int newnode()
        {
            for (int i=0; i<26; i++)
                next[L][i]=-1;
            end[L++]=0;
            return L-1;
        }
    void init()
        {
            L=0;root=newnode();
        }
    void insert(char s[])
        {
            int len=strlen(s);
            int now=root;
            for (int i=0; i<len; i++)
                {
                    if (next[now][s[i]-'a']==-1)
                        next[now][s[i]-'a']=newnode();
                    now=next[now][s[i]-'a'];
                }
            end[now]++;
        }
    void build()
        {
            queue <int> q;
            fail[root]=root;
            for (int i=0; i<26; i++)
                if (next[root][i]==-1)
                    next[root][i]=root;
                else
                    {
                        fail[next[root][i]]=root;
                        q.push(next[root][i]);
                    }
            while (!q.empty())
                {
                    int now=q.front();
                    q.pop();
                    for (int i=0; i<26; i++)
                        if (next[now][i]==-1)
                            next[now][i]=next[fail[now]][i];
                        else
                            {
                                fail[next[now][i]]=next[fail[now]][i];
                                q.push(next[now][i]);
                            }
                }
        }
    long long query(char s[])
        {
            int len=strlen(s);
            int now=root;
            long long re=0;
            for (int i=0; i<len; i++)
                {
                    now=next[now][s[i]-'a'];
                    int tmp=now;
                    while (tmp!=root)
                        {
                            re+=end[tmp];
                            end[tmp]=0;
                            tmp=fail[tmp];
                            //cout<<i<<endl;
                        }
                }
            return re;
        }
    void debug()
        {
            for (int i=0; i<L; i++)
                {
                    printf("id= %3d,fail= %3d,end= %3d,chi =[",i,fail[i],end[i]);
                    for (int j=0; j<26; j++)
                        printf("%2d",next[i][j]);
                    printf("]
");
                }
        }
};
char s[100000010];
char s1[201][1000010];
trie ac;
int main()
{
    int t;int n;
    scanf("%d",&n);
    for (int i=0; i<n; i++)
        {
            scanf("%s",s1[i]);
            s1[i][strlen(s1[i])]='&';
            strcat(s,s1[i]);
        }
    //puts(s);
    for (int i=0; i<n; i++)
        {
            ac.init();
            delete(s1[i],strlen(s1[i]),1);
            ac.insert(s1[i]);
            ac.build();
            printf("%I64d
",ac.query(s));
        }
    return 0;
}
原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346191.html