算法学习:后缀自动机

Posted rentu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法学习:后缀自动机相关的知识,希望对你有一定的参考价值。

【前置知识】

AC自动机(没有什么关联,但是看懂了会对后缀自动机有不同的理解)

 

【解决问题】

各种子串的问题

 

 

【算法学习】

学习后缀自动机的过程中,看到了许多相关性质和证明,但是奈何才疏学浅(lan)

暂时先放着,到有空再更

 

【算法分析】

后缀自动机和AC自动机和回文自动机的不同点在于

后缀自动机是个DAG,而AC自动机和回文自动机是

 

 

首先理解   endpos 数组,每个子串都有一个endpos数组,表示他在字符串中出现的位置的结束位置

而endpos数组相同的子串,就被称为endpos类

而显然易见的,endpos类中最长的子串,能够在子类中找到他的所有子串

而后缀自动机中的节点,就是endpos类,所代表的字符串,也可以表示为这个endpos类中最长的子串

 

节点之间的边,是互相之间的字母

通过字母走到节点,能够得到关于这个节点子串的后缀

即此节点所代表的整个 endpos 类

 

 

 

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define ll long long
using namespace std;
const int MAXN = 2*1e6 + 10;
const int CHAR = 27;
struct note

    int ch[CHAR];
    int fa;
    ll len;
dian[MAXN];
int zhi[MAXN];
int cnt=1, now=1;
char s[MAXN];
void insert(int c)

    int p = now, np = now = ++cnt; zhi[cnt] = 1;
    dian[np].len = dian[p].len + 1;
    for (;p && !dian[p].ch[c]; p = dian[p].fa) 
        dian[p].ch[c] = np;
    if (!p) dian[np].fa = 1;
    else
    
        int q = dian[p].ch[c];
        if (dian[q].len == dian[p].len + 1) dian[np].fa = q;
        else
        
            int nq = ++cnt;
            dian[nq] = dian[q];
            dian[nq].len = dian[p].len + 1;
            dian[q].fa = dian[np].fa = nq;
            for (; p && dian[p].ch[c] == q; p = dian[p].fa)
                dian[p].ch[c] = nq;
        
    

ll ans = 0;
int cd;
int st[MAXN],top;
struct NOTE

    int to;
    int nt;
edge[MAXN];
void add(int x, int y)

    top++; edge[top].nt = st[x]; edge[top].to = y; st[x] = top;

void dfs(int x)

    for (int i = st[x]; i != -1; i = edge[i].nt)
    
        dfs(edge[i].to);
        zhi[x] += zhi[edge[i].to];
    
    if (zhi[x] != 1) ans = max(ans, zhi[x] * dian[x].len);

int main()

    memset(st, -1, sizeof(st));
    scanf("%s", s); cd = strlen(s);
    //printf("**\n");
    for (int i = 0; i < cd; i++) insert(s[i] - a+1);
    //printf("**\n");
    for (int i = 2; i <= cnt; i++)
        add(dian[i].fa, i);
    //printf("**\n");
    dfs(1);
    printf("%lld\n", ans);

    return 0;

 

以上是关于算法学习:后缀自动机的主要内容,如果未能解决你的问题,请参考以下文章

算法后缀自动机SAM

算法后缀自动机(SAM)

模板后缀自动机 (SAM)

Bzoj2882 工艺 [香港算法]

学习笔记(SAM)

算法零基础KMPTrieAC自动机