【模板整合】SAM后缀自动机的构建

太弱了QAQ学完SAM这么久才学会构建QAQ

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 200010
using namespace std;
struct sam
{
    int p,q,np,nq;
    int cnt,last;
    int a[MAXN][26],len[MAXN],fa[MAXN];
    sam()
    {
        last = ++cnt;
    }
    void insert(int ch)
    {
        p = last;np = last = ++cnt;l[np] = l[p] + 1;
        //不断添加从当前状态到np的转移,直到发现一个状态p已经存在关于字符ch的转移,转以后状态为q 
        while (!a[p][ch] && p)  a[p][ch] = np,p = fa[p];        
        if (!p) fa[np] = 1;//有可能这个状态是自动机的初始状态 
        else
        {
            q = a[p][ch];//状态q为状态p经ch转移后得到的状态 
            //进行讨论,有len_q=len_p+1,len_q>len_p+1两种情况.
            if  (len[q] == len[p] + 1)  fa[np] = q;//此时直接令fa_np=q
            else
            {
                nq = ++cnt;len[nq] = len[p] + 1;//否则建立新状态nq,len_nq=len_p+1
                //nq代表原来串中长度不超过len_p+1的串,其fa和转移都和q一致 
                memcpy(a[nq],a[q],sizeof(a[q]));
                fa[nq] = fa[q];
                fa[np] = fa[q] = nq;
                while   (a[p][ch] == q) a[p][ch]=q,p=fa[p];
            } 
        }
    }
    void build()
    {
        char ch[MAXN];
        scanf("%s",ch);
        for (int i = 0;i < strlen(ch);i++)  insert(ch[i] - 'a');//对已知串构建后缀自动机 
    }
}
/*
int main()
{

}*/

我的代码注释一向很够看>_<
可以看到SAM在构建的时候是不断插入字符来构建的
也正因为这种方式,SAM能够做到别的字符串数据结构支持不了的在线插入字符
这也给了我们一个提示:
如果你面对一个字符串的题,模板串会在线插入字符或者题目要求强制在线,而数据范围又告诉你不能够通过重新预处理来更新出新版本的数据结构,那这个题必定是SAM无疑了.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值