E - You Are Given Some Strings... CodeForces - 1202E

#include <bits/stdc++.h>
#define FRER() freopen("i.txt","r",stdin);
using namespace std;
/*
ac自动机
我们考虑两个串的连接处,对于文本串,如果在t[i]匹配了x个,那么说明以
t[i]为结尾的串有x,反着找val[t[i]],说明以t[i]为结尾的串有x,记录乘积
来反应最终有多少贡献值
傻逼了,把int ch,弄成char ch了,我是憨憨
*/

typedef long long ll;
const int maxn=2e5+100,M=27;

struct ACH
{
    int ch[maxn][M];
    int f[maxn];
    int sz=1;
    int C[maxn];
    int val[maxn];
    void init()
    {
        memset(C,0,sizeof C);
        memset(f,0,sizeof f);
        memset(val,0,sizeof val);
    }
    int index(char c)
    {
        return c-'a';
    }
    void inser(char *s)
    {
        int len=strlen(s);
        int u=0;
        for(int i=0; i<len; i++)
        {
            int c=index(s[i]);
            if(!ch[u][c])
                ch[u][c]=sz++;
            u=ch[u][c];
        }
        val[u]++;
    }
    void getFile()
    {
        f[0]=0;
        queue<int>que;
        for(int i=0; i<M; i++)
        {
            if(ch[0][i])
                que.push(ch[0][i]),f[ch[0][i]]=0;
        }
        while(!que.empty())
        {
            int r=que.front();
            que.pop();
            val[r]+=val[f[r]];
            for(int i=0; i<M; i++)
            {
                int u=ch[r][i];
                if(!u)
                {
                    ch[r][i]=ch[f[r]][i];
                    continue;
                }
                que.push(u);
                int v=f[r];
                f[u]=ch[v][i];
            }
        }
    }
    int fin(char *s)
    {
        int len=strlen(s);
        int j=0;
        for(int i=0; i<len; i++)
        {
            j=ch[j][s[i]-'a'];
            C[i]=val[j];
        }
    }
} ach,ach1;
int main()
{
    char s[maxn],s1[maxn];
    int n;
    scanf("%s",s);
    scanf("%d",&n);
    ach.init(),ach1.init();
    for(int i=0; i<n; i++)
    {
        scanf("%s",s1);
        ach.inser(s1);
        reverse(s1,s1+strlen(s1));
        ach1.inser(s1);
    }
    ach.getFile(),ach1.getFile();
    ach.fin(s);
    int len=strlen(s);
    reverse(s,s+strlen(s));
    ach1.fin(s);
    ll ans=0;
    for(int i=0; i<len-1; i++)//是len-1,不是len
    {
       // printf("i=%d ach.C[i]=%d %d %d\n",i,ach.C[i],ach1.C[len-i-2],len-i-2);
        ans+=(ll)ach1.C[i]*(ll)ach.C[len-i-2];
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zhangzhenjun/p/11746002.html