Prefixes and suffixes SGU - 505

题意:给n个字符串 和m个字符串对 问对于每个字符串对 他最多是n里面多少个字符串的前缀和后缀

一道比较基础的AC自动机的题目 简单点说就是重新构造字符串和需要匹配的字符串对

以样例为例:

aaaaa 就改造为aaaaa}aaaaa 中间那个是26个字母之后的一个字符

而字符串对于a aa为例就改造为aa}a

可以看到假设字符串分别是字符串的前缀和后缀的话那么在两者的“}”两边必然是可以匹配的 那么

问题就转化为对于n个字符串和m个字符串 判断n中每个字符串最多包含多少个m中的字符串 这恰好

就是AC自动机的模型。

感谢一位师兄的shared code 代码思路很清晰 非常有帮助

代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define maxn 222222
vectorv;
char a[maxn],pre[maxn],suf[maxn],buf[maxn];
int ans[maxn],num[maxn];
int n,m,be[maxn];
struct ato
{
    int fail[maxn],end[maxn],val[maxn];
    int next[maxn][28];
    int root,L;
    int newnode()
    {
        for(int i=0;i<27;i++) next[L][i]=-1;
        end[L++]=0;
        return L-1;
    }
    void ini()
    {
        L=0;
        root=newnode();
    }
    void insert(int id)
    {
        int len=strlen(buf);
        int now=root;
        for(int i=0;iq;
        fail[root]=root;
        for(int i=0;i<27;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();
            v.push_back(now);
            q.pop();
            for(int i=0;i<27;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]);
                }
            }
        }
    }
    void query()
    {
        int len=strlen(buf);
        int now=root;
        for(int i=0;i=0;i--)
        {
            num[fail[v[i]]]+=num[v[i]];
        }
    }

}ac;
int main()
{
    ac.ini();
    scanf("%d",&n);
    int now=0;
    for(int i=1;i<=n;i++)
    {
        be[i]=now;
        scanf("%s",a+now);
        while(a[now]) now++;
    }
    be[n+1]=now;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%s%s",pre,suf);
        int len=strlen(suf);
        int len1=strlen(pre);
        int cnt=0;
        for(int j=0;j


你可能感兴趣的:(算法竞赛,自动机)