ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

109 后缀自动机(SAM)

2022-04-16 10:02:33  阅读:195  来源: 互联网

标签:ch cur SAM fa 后缀 len int 109 nq


视频链接:

 

 

 

 

 

 

 

 

 

 

 

 

P3804 【模板】后缀自动机 (SAM)

// Luogu P3804 【模板】后缀自动机 (SAM)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;
const int N=2e6+10;
int h[N], e[N], ne[N], idx;
char str[N];
LL cnt[N], ans;
int tot=1, cur=1;
int len[N], fa[N], ch[N][26];

void extend(int c){
  // p指针,cur当前点,q链接点,nq新链接点
  int p = cur; cur = ++tot;
  len[cur]=len[p]+1; cnt[cur]=1;
  for(; p&&!ch[p][c]; p=fa[p]) ch[p][c]=cur;

  if(p==0) fa[cur]=1;//1.c是新字符
  else{
    int q=ch[p][c];
    if(len[q]==len[p]+1)fa[cur]=q;//2.有链接点
    else{ //3.无链接点
      int nq = ++tot; //新建链接点
      len[nq]=len[p]+1; 
      fa[nq]=fa[q]; fa[q]=nq; fa[cur]=nq;
      memcpy(ch[nq],ch[q],sizeof(ch[q]));
      for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq; 
    }
  }
}
void add(int a, int b){
    e[++idx]=b, ne[idx]=h[a], h[a]=idx;
}
void dfs(int u){
    for(int i=h[u]; i; i=ne[i]){
        dfs(e[i]);
        cnt[u] += cnt[e[i]];
    }
    if(cnt[u]>1) ans=max(ans, cnt[u]*len[u]);
}
int main(){
    scanf("%s", str);
    for(int i=0;str[i];i++) extend(str[i]-'a');
    for(int i=2; i<=tot; i++) add(fa[i], i);
    dfs(1);
    printf("%lld\n", ans);
    return 0;
}

 

标签:ch,cur,SAM,fa,后缀,len,int,109,nq
来源: https://www.cnblogs.com/dx123/p/16152016.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有