spoj1811 LCS - Longest Common Substring

分析

我们可以建出s串的parent树

然后t串在上面跳着找即可

代码

#include<bits/stdc++.h>
using namespace std;
char s[300100],t[300100];
int n,m,Ans;
struct SAM {
    int mp[1000100][30],fa[1000100],ed=1,ccnt=1,len[1000100];
    int cnt,head[1000100],nxt[1000100],to[1000100];
    inline void ins(int x,int n1){
      int p=ed;
      ed=++ccnt;
      len[ccnt]=n1;
      while(p&&!mp[p][x]){
          mp[p][x]=ed;
          p=fa[p];
      }
      if(!p){
          fa[ed]=1;
          return;
      }
      int q=mp[p][x];
      if(len[p]+1==len[q]){
          fa[ed]=q;
          return;
      }
      len[++ccnt]=len[p]+1;
      for(int i=1;i<=26;i++)mp[ccnt][i]=mp[q][i];
      fa[ccnt]=fa[q];
      fa[q]=ccnt;
      fa[ed]=ccnt;
      for(int i=p;mp[p][x]==q;i=fa[i])mp[i][x]=ccnt;
    }
    inline void add(int x,int y){nxt[++cnt]=head[x];head[x]=cnt;to[cnt]=y;}
    inline void build(){for(int i=2;i<=n;i++)add(fa[i],i);}
    inline void work(){
      int p=1,res=0;
      for(int i=1;i<=m;i++){
          int x=t[i]-'a'+1;
          if(mp[p][x])res++,p=mp[p][x];
            else {
                while(p&&!mp[p][x])p=fa[p];
                if(p)res=len[p]+1,p=mp[p][x];
                  else res=0,p=1;
          }
        Ans=max(Ans,res);
      }
    }
};
SAM sam;
int main(){
    int i,j,k;
    scanf("%s%s",s+1,t+1);
    n=strlen(s+1);
    m=strlen(t+1);
    for(i=1;i<=n;i++)sam.ins(s[i]-'a'+1,i);
    sam.build();
    sam.work();
    printf("%d\n",Ans);
    return 0;
}

 

posted @ 2019-09-06 07:49  水题收割者  阅读(136)  评论(0编辑  收藏  举报