首页 > 其他分享 >【板子】后缀自动机(SAM)

【板子】后缀自动机(SAM)

时间:2024-01-26 21:15:24浏览次数:28  
标签:ch SAM fa 后缀 len int np nq 自动机

//lg 3804
//Copyright yeyou26
//注意:这道题不是纯纯的后缀自动机,main函数有一点额外处理
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define N (int(2e6+6))

int fa[N];
int ch[N][28];
int len[N];
int cnt[N];
ll ans;
int idx=1;
int np=1;

string s;

vector<int> e[N];

void init();
void Addsam(int c);
ll calculate();
void dfs(int u);

int main()
{
    freopen("working.in","r",stdin);
    freopen("working.out","w",stdout);
    init();
    for(int i=0;s[i];i++)
    {
        Addsam(s[i]&31);
    }
    for(int i=2;i<=idx;i++)
    {
        e[fa[i]].push_back(i);
    }
    dfs(1);
    cout<<ans;
    return 0;
}

//Function Implementation

void dfs(int u)
{
    for(int v : e[u])
    {
        dfs(v);
        cnt[u]+=cnt[v];
    }
    if(cnt[u]>1) ans=max(ans,(ll)cnt[u]*len[u]);
}

void Addsam(int c)
{
    //p回跳指针 np新节点 q链接点 nq分裂链接点
    int p=np,np=++idx;
    len[np]=len[p]+1;
    cnt[np]=1;
    for(;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
    //case 1 找不到任何出现过(新串后缀)
    if(p==0) fa[np]=1;
    else 
    {   
        int q=ch[p][c];
        //case 2 链接点合法,直接连
        if(len[q]==len[p]+1) fa[np]=q;
        else 
        {
            //case 3 链接点不合法,裂开为nq和q,q负责长度大于len(p)+1的串,nq负责长度小于等于len(p)+1的串
            int nq=++idx;
            len[nq]=len[p]+1;
            fa[nq]=fa[q];fa[q]=nq;fa[np]=nq;
            //指向q的转移边指向nq
            for(;p && ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
            //从q出发的转移边丢给nq一份
            memcpy(ch[nq],ch[q],sizeof(ch[q]));  
        }
    }
}

void init()
{
    cin>>s;
}

标签:ch,SAM,fa,后缀,len,int,np,nq,自动机
From: https://www.cnblogs.com/yeyou26/p/17990712

相关文章

  • 01.23 算法补全:后缀数组
    秉着技多不压身的想法,我认为在有些时候后缀数组的直接建法还是有用处的,于是决定快速地补一下这个算法。以后看看能不能每天稳定产出一篇,随便什么的文章。可能是一个trick的记录,也能是算法补全,或者是题解慢报/速报,亦或是鲜花。这些内容会同步发表于我的洛谷blog:https://www.luo......
  • OpenAI首席执行官Sam Altman与中东投资者和台积电讨论合作,共同开创新一代芯片企业
    Ai工具集导航(Ai-321.com)OpenAI首席执行官SamAltman目前正怀着雄心壮志与中东投资者和著名芯片制造商台积电(TSMC)进行讨论,意图共同创立一家全新的芯片企业。消息人士透露,此举是为了满足OpenAI公司对半导体的持续快速增长需求,并同时减少对英伟达的依赖。这位年仅38岁的企业家已经与......
  • BZOJ1717 Milk Patterns 产奶的模式 (二分+后缀数组+height数组)
    发现这样起标题更能引流(ylg实锤了)题意给定一个长度为\(n\)的数组\(a\),求在\(a\)中出现了至少\(k\)次的最长子串的长度。解法考虑将一个子串拆成两个后缀,即\([l,r]=[l,n]-[r,n]\),发现一个长度为\(x\)的子串\(t\)在\(i,j\)两个位置出现过当且仅当后缀\(i,j\)有......
  • 【学习笔记】后缀自动机 SAM
    一.后缀自动机的定义SAM(SuffixAutomaton)是一种有限状态自动机,仅可以接受一个字符串的所有后缀。如果您不懂自动机,那么换句话说:SAM是一个有向无环图。称每个结点为状态,边为状态间的转移,每个转移标有一个字母,同一节点引出的转移不同。SAM存在一个源点\(S\),称为初始状态......
  • SA&SAM 小记
    0.Front纯笔记,不含教学内容,部分有拓展,部分太简单所以以”显然“带过了,总结了部分oi-wiki的内容。字符串为\(S\),长度为\(n\),且应有\(|\Sigma|\len\)。通常来说,大写字母表示为字符串,小写字母表示为字符。后缀的编号为\(i\),表示是以\(i\)为起点的后缀。基础小练习1.......
  • 浅谈 AC 自动机
    浅谈AC自动机前言这不是第一次看到这个算法。第一次是在OI-wiki上瞄到的。当时我还是一个什么也不懂的初一蒟蒻,看到这个名字就十分兴奋:“‘AC自动机’耶!是不是可以帮我自动AC!?”后来看到只是一个字符串算法,就离开了。今天上课讲了这个,感觉原理及实现没有后缀数组那么难......
  • AC 自动机学习笔记
    AC自动机学习笔记AC自动机可以用于解决字符串上的出现次数,出现位置问题。结合了Trie树和KMP的思想,在\(O(n)\)的时间内完成查询。相较于KMP的好处在于,AC自动机不仅速度快,而且支持多个模式串同时在一个文本串内查询。算法前置知识:Trie树,KMP,自动机基本概念。构建AC......
  • CodeForces 1266F Almost Same Distance
    洛谷传送门CF传送门好厉害。特判\(k=1\)。首先经过观察,我们可以按照\(k\)的奇偶性讨论:\(k\)为偶数,有一个中心点挂了若干条长度为\(\frac{k}{2}\)的链。\(k\)为偶数,有两个中心点,两边挂了若干条长度为\(\frac{k}{2}\)的链;\(k\)为奇数,有一个中心点挂了若干条长度......
  • 后缀数组 SA 学习笔记
    后缀数组SA学习笔记后缀数组处理字符串后缀排名,公共子串类问题十分优秀,可以在部分情况下替代后缀自动机(SAM),本文主要讲解后缀数组的实现过程和部分例题。正文定义后缀:从\(i\)开始到字符串结束的一个特殊子串,本文用\(suf(i)\)表示从\(i\)开始的后缀。后缀数组SA:SA是......
  • MYISAM和INNODB的区别
    INNODB支持事务,而MYISAM不支持事务。INNODB支持外键,而MYISAM不支持外键。MYISAM中B+Tree的数据结构存储的内容是实际数据的地址值,它的索引和实际数据是分开的,只不过使用索引指向了实际数据。这种索引的模式被称为非聚集索引。InnoDB中B+树的数据结构中存储的都是实......