UVA-11019Matrix Matcher(AC自动机)

题目的大意是对于给定的文本串和模板串,要求出模板串在文本串中出现的次数,那么很显然可以先对模板串一行一行的进行构建Trie树,而后对于文本串也一行一行的进行匹配寻找,在寻找的过程中对相应的行列进行记录就可以了,其中要注意的是模板串中可能重复字符串,即不同行的字符串相同,因而要另设一数组进行相应的记录,妥妥的一道AC自动机题。


值得一提的是本题可以用Hash的思想去做,并且时间复杂度可以降到50ms(AC自动机的时间复杂度达到2000+ms),但其构造过程比较奇特,博主自己的Hash也不是很会- -.....有兴趣得可以到VJUDGE上搜索题目后看LeaderBoad,代码是公开的。


下面是AC自动机的代码

#include
#include
#include
#include
using namespace std;
char ax[1005][1005],ac[105][105];
int cnt[1005][1005],N,M,X,Y;
const int maxn=105*105;
int Next[maxn][27],fail[maxn],value[maxn],last[maxn],My[maxn];
struct Trie
{
    int L,root;
    int getNewnode()
    {
        for(int i=0;i<26;i++)
            Next[L][i]=0;
        value[L++]=0;
        return L-1;
    }
    void init()
    {
        memset(cnt,0,sizeof(cnt));
        memset(My,0,sizeof(My));
        L=0;
        root=getNewnode();
        return ;
    }
      void Insert(char* s,int id)
    {
        int p=root;
        int len=strlen(s);
        for(int i=0;i q;
       for(int i=0;i<26;i++)
       {
           int u=Next[0][i];
           if(u)
           {
               fail[u]=0;
               last[u]=0;
               q.push(u);
           }
       }
       while(!q.empty())
       {
          int p=q.front();
          q.pop();
          for(int i=0;i<26;i++)
            {
                int temp=Next[p][i];
                if(!temp)
                {
                    Next[p][i]=Next[fail[p]][i];
                    continue;
                }
                q.push(temp);
                int v=fail[p];
                while(v&&!Next[v][i])
                    v=fail[v];
                fail[temp]=Next[v][i];
                last[temp]=value[fail[temp]]?fail[temp]:last[fail[temp]];
            }
       }
    }
    void print(int x,int y,int j)
    {
        if(j)
        {
             if(x-value[j]+1>=0)
                cnt[x-value[j]+1][y]++;
              int t =value[j];
             while(My[t])
             {
                 t=My[t];
                 if(x-t+1>=0)
                    cnt[x-t+1][y]++;

             }
           print(x,y,last[j]);
        }
    }
    void find1(char* s,int r)
    {
      int p=root;
      int len=strlen(s);
      for(int i=0;i



你可能感兴趣的:(AC自动机)