spoj1811

题解:

后缀自动机

先把A的后缀自动机建好

然后用B再上面跑

如果不能转移就跳fail

如果可以就到下一个可行状态

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=250005;
char b[N],a[N];
int n,m,cnt,la;
struct State
{
    int ch[26],fa,len;
    void init()
     {
         fa=-1;
         len=0;
         memset(ch,-1,sizeof ch);
     }
}T[N*2];
void Extend(int c)
{
    int end=++cnt,tmp=la;
    T[end].init();
    T[end].len=T[tmp].len+1;
    while (tmp!=-1&&T[tmp].ch[c]==-1)
     {
         T[tmp].ch[c]=end;
         tmp=T[tmp].fa;
     }
    if (tmp==-1)T[end].fa=0;
    else
     {
         int ne=T[tmp].ch[c];
         if (T[tmp].len+1==T[ne].len)T[end].fa=ne;
         else
          {
              int np=++cnt;
              T[np]=T[ne];
              T[np].len=T[tmp].len+1;
              T[end].fa=T[ne].fa=np;
              while (tmp!=-1&&T[tmp].ch[c]==ne)
               {
                   T[tmp].ch[c]=np;
                   tmp=T[tmp].fa;
               }
          }
     } 
    la=end; 
}
void solve()
{
    int ans=0;
    T[0].init();
    for (int i=1;i<=n;i++)Extend(a[i]-'a');
    int Lcs=0,o=0;
    for (int i=1;i<=m;i++)
     {
         int c=b[i]-'a';
         if (T[o].ch[c]!=-1)
          {
              o=T[o].ch[c];
              ans=max(ans,++Lcs);
          }
         else
         {
             while (o!=-1&&T[o].ch[c]==-1)o=T[o].fa;         
             if (o==-1)o=Lcs=0;
             else
              {
                  Lcs=T[o].len+1;
                  o=T[o].ch[c];
                  ans=max(ans,Lcs);
              }
         }
     } 
    printf("%d
",ans); 
}
int main()
{
    scanf("%s%s",a+1,b+1);
    n=strlen(a+1);
    m=strlen(b+1);
    solve();
    return 0;
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8584823.html