SAM(后缀自动机)总结

“写sam是肯定会去写的,这样才学的了字符串,后缀数组又不会用 >ω<,

sam套上数据结构的感觉就像回家一样!

里面又能剖分又能线段树合并,调试又好调,我爱死这种写法了 !qwq”

SAM是一个DFA,它存储了某字符串的所有子串信息。

待更。

博主水平不行,尽量在退役前多更些。

插入字符:

 1 void extend(int id,int&now)
 2 {
 3     int p=now;
 4     if(ch[p][id] && len[ch[p][id]]==len[p]+1)
 5     {
 6         now=ch[p][id];
 7         return;
 8     }
 9     int np=++tot;
10     len[np]=len[p]+1;
11     while(p && !ch[p][id])
12     {
13         ch[p][id]=np;
14         p=fa[p];
15     }
16     if(!p)
17     {
18         fa[np]=1;
19     }
20     else
21     {
22         int q=ch[p][id];
23         if(len[q]==len[p]+1)
24         {
25             fa[np]=q;
26         }
27         else
28         {
29             int nq=++tot;
30             len[nq]=len[p]+1;
31             fa[nq]=fa[q];
32             for(int i=0;i<26;i++)
33                 ch[nq][i]=ch[q][i];
34             fa[q]=fa[np]=nq;
35             while(p && ch[p][id]==q)
36             {
37                 ch[p][id]=nq;
38                 p=fa[p];
39             }
40         }
41     }
42     now=np;
43 }

套路:

每条路径与子串一一对应。

$len_i$:该节点最长串的长度

$Parent Tree$上的子树和:串的出现次数

$len_i - len_{fa_i}$:该节点代表的串的数目

部分题目选:

(1)[SAM入门题][NOI2018]你的名字

题目链接

线段树合并维护$right$集合

(2)[SAM入门题][CTSC2012]熟悉的文章

题目链接

$SAM$只是用来预处理的,求答案还要靠二分+单队$DP$

(3)[SAM入门题][bzoj2555]Substring

题目链接

$LCT$对$Parent Tree$结构的维护

(4)[bzoj3277]字符串

题目链接

广义后缀自动机的应用

暴力搞复杂度大概是根号的,不会证明。

(5)[bzoj5084]HASHIT

题目链接

带撤销后缀自动机,随机数据随便艹。

(6)[USACO]牛奶模式

题目链接

后缀自动机的基本原理与使用

(7)[洛谷元旦赛]WD与数列

题目链接

维护$right$集合的好题(似乎还要在parent树上跑启发式合并计算贡献,我并不会)

(8)[FZOJ2258]封印

题目链接暂不提供

大概就是你知道$Parent$树是干啥的,形态如何,就能直接切掉。

upd:话说为啥没见过把状态设在sam节点上的DP题?

upd:CF700E,已经单独更新

转载于:https://www.cnblogs.com/bestwyj/p/10152256.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值