算法学习:后缀自动机

【前置知识】

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;
}

原文地址:https://www.cnblogs.com/rentu/p/11508652.html

时间: 2024-11-05 21:48:33

算法学习:后缀自动机的相关文章

算法学习 - 后缀表达式 (C++ 栈实现)

后缀表达式就是把一个式子进行树的后序遍历.然后根据这个顺序来求值. 栈来实现的时候很简单. 例如中缀表达式:6 * [ 5 + ( 2 + 3 )  * 8 + 3 ] 则 后缀表达式为:6 5 2 3 + 8 * + 3 + * 下面上代码: // // main.cpp // postfixExpression // // Created by Alps on 14-7-28. // Copyright (c) 2014年 chen. All rights reserved. // #inc

后缀自动机(SAM)学习指南

*在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符串所有后缀的自动机. 它最早在陈立杰的 2012 年 noi 冬令营讲稿中提到. 在2013年的一场多校联合训练中,陈立杰出的 hdu 4622 可以用 SAM 轻松水过,由此 SAM 流行了起来. 一般来说,能用后缀自动机解决的问题都可以用后缀数组解决.但是后缀自动机也拥有自己的优点. 1812.

后缀自动机(SAM)

*在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符串所有后缀的自动机. 它最早在陈立杰的 2012 年 noi 冬令营讲稿中提到. 在2013年的一场多校联合训练中,陈立杰出的 hdu 4622 可以用 SAM 轻松水过,由此 SAM 流行了起来. 一般来说,能用后缀自动机解决的问题都可以用后缀数组解决.但是后缀自动机也拥有自己的优点. 1812.

『后缀自动机入门 SuffixAutomaton』

本文的图片材料多数来自\(\mathrm{hihocoder}\)中详尽的\(SAM\)介绍,文字总结为原创内容. 确定性有限状态自动机 DFA 首先我们要定义确定性有限状态自动机\(\mathrm{DFA}\),一个有限状态自动机可以用一个五元组\((\mathrm{S},\Sigma,\mathrm{st},\mathrm{end},\delta)\)表示,他们的含义如下: \(1.\) \(\mathrm{S}\) 代表自动机的状态集 \(2.\) \(\Sigma\) 代表字符集,也称字

算法学习 - 表达树的建立(后缀表达式法),树的先序遍历,中序遍历,后序遍历

表达树就是根据后缀表达式来建立一个二叉树. 这个二叉树的每个叶子节点就是数,真祖先都是操作符. 通过栈来建立的,所以这里也会有很多栈的操作. 树的先序遍历,中序遍历,后序遍历的概念我就不讲了,不会的自行百度,不然也看不懂我的代码. 下面是代码: // // main.cpp // expressionTree // // Created by Alps on 14-7-29. // Copyright (c) 2014年 chen. All rights reserved. // #includ

后缀自动机学习小记

简介 后缀三姐妹:后缀数组,后缀自动机,后缀树. 后缀自动机:Suffix Automation,也叫SAM. 创立算法的思路来源:能不能构出一个自动机(本质就是一个有向图),能识别一个串的所有后缀. 识别所有后缀基础想法 把所有的后缀都放进一个trie里面,比如串aabbabd. 这样的状态太多了,怎么把状态数缩小. 减小状态数的方法 定义一个子串的right集合为这个子串在原串中出现的右端点集合. 如果两个子串A和B的right集合完全相同的话,那么他们明显一个是另一个的后缀,假设A是B的后

算法学习:后缀数组 height的求取

[定义] [LCP]全名最长公共前缀,两个后缀之间的最长前缀,以下我们定义 lcp ( i , j ) 的意义是后缀 i 和 j 的最长前缀 [z函数] 函数z [ i ] 表示的是,第 i 个后缀和字符串的最长前缀  [解决问题] 这两个算法都是在解决这个问题 即求后缀和字符串和后缀之间的最长公共前缀 但是有所不同的是, 后缀数组最终求出的是,字典序第 i 个后缀和第 i + 1 个后缀的最长公共前缀 z函数最终求出的是,第 i 个后缀和字符串的最长公共前缀 然后通过这个最长公共前缀求一些其他

@算法 - [email&#160;protected] 后缀自动机

目录 @0 - 参考资料@ @0.5 - 引言@ @1 - what is [email protected] @自动机@ @DAWG@ @终点集合 [email protected] @后缀链接 与 parent 树@ @2 - how to build [email protected] @理论@ @代码@ @3 - where can it [email protected] @0 - 参考资料@ Menci's Blog 的讲解 陈立杰冬令营的课件 @0.5 - 引言@ 后缀自动机(Su

[转]后缀自动机

原文地址:http://blog.sina.com.cn/s/blog_8fcd775901019mi4.html 感觉自己看这个终于觉得能看懂了!也能感受到后缀自动机究竟是一种怎样进行的数据结构了... 笔者自己的话会用楷体表示出来...[说不定能帮助大家理解,但是可能也破坏了大家的自主理解力?所以...看不懂的话再来看好咯...] 常用的字符串处理工具: 1.       整词索引:排序+二分:Hash表.可以解决整词匹配,但不支持前缀搜索:Hash表在模式串定长的情况下可以用RK解决多模式