后缀自动机

https://www.luogu.org/blog/Kesdiael3/hou-zhui-zi-dong-ji-yang-xie

代码

#include<bits/stdc++.h>
using namespace std;
char s[2000100];
long long Ans;
int n;
struct SAM {
    int mp[2000100][30],fa[2000100],ed,ccnt,len[2000100],siz[2000100];
    int head[2000100],nxt[2000100],to[2000100],cnt;
    inline void ins(int x,int n1){
      int p=ed;
      ed=++ccnt;
      siz[ccnt]=1;
      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[i][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<=ccnt;i++)add(fa[i],i);}
    inline void dfs(int x){
      for(int i=head[x];i;i=nxt[i])
        dfs(to[i]),siz[x]+=siz[to[i]];
      if(siz[x]!=1)Ans=max(Ans,1ll*siz[x]*len[x]);
    }
};
SAM sam;
int main(){
    int i,j,k;
    scanf("%s",s+1);
    n=strlen(s+1);
    sam.ed=sam.ccnt=1; 
    for(i=1;i<=n;i++)sam.ins(s[i]-'a'+1,i);
    sam.build();
    sam.dfs(1);
    printf("%lld\n",Ans);
    return 0;
}

 

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