2018.07.17 后缀自动机模板(SAM)】的更多相关文章

洛谷传送门 这是一道后缀自动机的模板题,这道题让我切身体会到了后缀自动机的方便与好写. 代码如下: #include<bits/stdc++.h> #define N 2000005 #define ll long long using namespace std; char s[N]; int a[N],siz[N],n,tot[N],root=1; ll ans=0; struct suf{ int last,cnt,ch[N<<1][26],fa[N<<1],le…
一点疑问: 当创建nq节点时,要不要把nq的cnt标记赋值为1? 讲道理nq节点也是代表一个子串啊,不过网上的模板都没赋值. 2017.9.18 update: 把memset部分重写,改成用节点用到时再初始化,初始化所有节点可能被卡. fa,len,cnt数组其实不用清空,因为用时都赋值了. struct SAM { <<;//大小为字符串长度两倍 ; int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN]; int sum[MAXN…
链接:https://ac.nowcoder.com/acm/contest/558/A来源:牛客网 A.串串 小猫在研究字符串. 小猫在研究字串. 给定一个长度为N的字符串S,问所有它的子串Sl…r(1≤l≤r≤N),去重后有多少种. 输入描述: 一行一个字符串S. 输出描述: 一行一个整数,表示答案. 示例1 输入 复制 ababa 输出 复制 9 备注: 1≤N≤10 5 ,字符都是小写字母 后缀自动机模板题,因为数据太大,极限可能为1e10,要开long long 不会后缀自动机,贴个板…
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意: 先输入一个长度为 n 的字符串, 然后有 q 个形如 l, r 的询问, 对于每个询问输出区间 [l, r] 中有多少不同的子串 思路: 后缀自动机模板 代码: // 后缀自动机要理解其含义,从起点到每个点的不同路径,就是不同的子串. // 到每一个点,不同路径,其实就是以这个点为最后一个字符的后缀,长度是介于(p->fa->len,p->len]之间的,个数也就清楚了. /…
传送门 就是给两个字符串,让你求公共字串的个数. 本来大佬们都是用的广义后缀自动机,但我感觉后缀自动机已经可以做这道题了.我们对其中一个字串建出后缀自动机,然后用另外一个后缀自动机在上面统计贡献即可. 代码如下: #include<bits/stdc++.h> #define N 400005 #define ll long long using namespace std; char s[N]; int ch[N][26],n,root=1,tot[N],a[N]; ll ans=0,len…
*在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符串所有后缀的自动机. 它最早在陈立杰的 2012 年 noi 冬令营讲稿中提到. 在2013年的一场多校联合训练中,陈立杰出的 hdu 4622 可以用 SAM 轻松水过,由此 SAM 流行了起来. 一般来说,能用后缀自动机解决的问题都可以用后缀数组解决.但是后缀自动机也拥有自己的优点. 1812.…
解决子串相关问题的强大工具 我们知道一个长度为 \(n\) 的字符串中所有的子串数目为 \(O(n^2)\) 个,这很大程度上限制了我们对某些子串相关问题的研究.所以有没有解决方案,使得我们可以在可承受的复杂度内表示出所有的子串? 于是,一种被称作 \(\text{DAWG}\) 的自动机(字符串 \(s\) 的 DAWG 简称 \(\text D_{s}\))横空出世.它可以做到仅用 \(O(n)\) 的状态数或转移数,表示出 \(s\) 的所有子串,并且 DAWG 可以在线性时间内增量构造.…
经过一顿操作之后竟然疑似没退役0 0 你是XCPC选手吗?我觉得我是! 稍微补一点之前丢给队友的知识吧,除了数论以外都可以看看,为Dhaka和新队伍做点准备... 不错的零基础教程见 IO WIKI - 后缀自动机,这篇就从自己的角度总结一下吧,感觉思路总是和别人不一样...尽量用我比较能接受的语言和逻辑重新组织一遍. 注意:在本文中,字符串的下标从1开始. 目前的 SAM 模板: const int N=100005; const int C=26; //注意检查字符集大小! //在结构题外开…
目录 定义 SAM 的状态集 一些性质 SAM 的后缀链接 SAM 的转移函数 一些性质 算法构造 构造方法 时间复杂度证明 状态的数量 转移的数量 代码实现 实际应用 统计本质不同的子串个数 计算任意子串出现次数 统计所有本质不同子串的权值和 求循环串在原串中出现次数 SAM 上博弈与 trans 上查询 题意 题解 此篇博客大部分内容来自于 hihoCoder , 借此学习 !! (侵删) 主要是上面讲的通俗易懂qwq 本文只是将其用更好的格式进行展现,希望对读者有帮助. 而且以后博客的 m…
http://poj.org/problem?id=1509 后缀自动机其实就是一个压缩储存空间时间(对节点重复利用)的储存所有一个字符串所有子串的trie树,如果想不起来长什么样子可以百度一下找个图回忆,从0开始到任意一个点的串都是字符串的子串. 有一些很好用的性质. 字符串的最小表示就是把一个字符串首尾相连再从任意一个地方断开产生的字典序最小的字符串,这个题是求最小表示的开头字母在原字符串中的下标(从1开始). 具体看实现吧,没什么可以解释的地方. #include<iostream> #…
后缀自动机+dp. 后缀自动机主要是在functioner大牛那里学习的:http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html 这道题是在No_stop大牛那里学习的:http://blog.csdn.net/no__stop/article/details/11784715 特别感谢这两位大牛!贴上代码作为以后的模板吧. #include<algorithm> #include<iostream> #include<cst…
Longest Common Substring 题意 求两个串的最长公共子串. 分析 第一个串建后缀自动机,第二个串在自动机上跑,对于自动机上的结点(状态)而言,它所代表的最大长度为根结点到当前结点的长度,而它的前继结点的串一定是这个结点串的后缀串(或空串). 匹配过程中一旦失配,自动机上的结点找它的前继结点,继续向后匹配即可. code #include<bits/stdc++.h> using namespace std; const int MAXN = 250005; char s[…
题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机然后记录这个子串个数 两个值相减即可 #include <set> #include <map> #include <stack> #include <queue> #include <cmath> #include <ctime> #i…
后缀自动机的入门博客 https://www.luogu.org/blog/Kesdiael3/hou-zhui-zi-dong-ji-yang-xie 有两种求法,分别对应了两种性质 #include<bits/stdc++.h> using namespace std; #define maxn 200005 char s[maxn]; int n; int cmp(int a,int b); struct SAM{ int cnt,last; ]; int link[maxn]; int…
用后缀自动机实现求两个串的最长公共子串. #include <cstdio> #include <algorithm> ; char s[N]; ]; int main() { scanf("%s", s); ; s[i]; i++) { int c = s[i]-'a', u = lst; ; u && !ch[u][c]; u = f[u]) ch[u][c] = sz; int x = ch[u][c]; if(!x) {ch[u][c]…
题目 [GDKOI2003]最大公共子串 [题目描述] 从一个给定的串中删去(不一定连续地删去)0个或0个以上的字符,剩下的字符按原来的顺序组成的串是该串的字串.例如:"", "a", "aaa","bbb","xabb","xaaabbb"都是串"xaaabbb"的字串.(例子中的串不包括引号) 编程求N个非空串的最长公共子串的长度. 限制:2<=N<=…
后缀数组: #include<cstdio> #include<algorithm> #include<cstring> #include<vector> using namespace std; typedef long long ll; ,mod=; char s[N]; ],Log[N]; void Sort(int* x,int* y,int m) { ; i<m; ++i)c[i]=; ; i<n; ++i)++c[x[i]]; ; i…
传送门 一道简单的字符串.这里收集了几种经典做法: SAM,不想写. 后缀数组+二分,不想写 后缀数组+单调队列,不想写 hash+二分,for循哈希,天下无敌!于是妥妥的hash 代码如下: #include<bits/stdc++.h> #define N 20005 #define Base 20001 using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=g…
洛谷传送门 bzoj传送门 这道题要用到学习莫比乌斯反演时掌握的整除分块算法,也就是对于一个数n" role="presentation" style="position: relative;">nn,n" role="presentation" style="position: relative;">nn除以1" role="presentation" style…
传送门 好的一道最小表示法的裸板,感觉跑起来贼快(写博客时评测速度洛谷第二),这里简单讲讲最小表示法的实现. 首先我们将数组复制一遍接到原数组队尾,然后维护左右指针分别表示两个即将进行比较的字符串的头尾.然后开始逐位比较,当两个字串同一位置的字符不同时,相对来说字符值较大的指针跳到失配下标的后面一位,如果此时两个指针重合,将其中一个加一.边界条件:两个指针中有一个值大于原数组长度. 代码如下: #include<bits/stdc++.h> #define N 300005 using nam…
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 4000005 using namespace std; int n,v[N],du[N],head[N],ver[N],nxt[N],tot; void add(int a,int b) { tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;retu…
P3804 [模板]后缀自动机 后缀自动机模板 详情可见luogu题解板块 #include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; ll max(ll a,ll b){return a>b?a:b;} #define N 2000005 struct Sam{ ],fa[N],len[N],siz[N]; int n,p,q,l…
传送门 后缀自动机模板题. 题意简述:求两个字串的最长公共子串长度. 对其中一个构建后缀自动机,用另外一个在上面跑即可. 代码: #include<bits/stdc++.h> #define ri register int using namespace std; const int N=5e5+5; int n; char s[N]; struct SAM{ int tot,last,rt,len[N],son[N][26],link[N]; SAM(){tot=last=rt=1,len…
后缀自动机模板题. 关键时求解每个节点的 $right$ 大小. 由于后缀自动机在构建时会保证点和点的 $right$ 只可能没有交集,或者一个是另一个的真子集,我们可以不重复的对 $right$ 进行统计与更新. 从长度大的子串向前更新,沿着 $parent$ 跳即可. 最后再枚举一下. Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) freopen(s&…
模板来源:http://blog.csdn.net/zkfzkfzkfzkfzkfzkfzk/article/details/9669747 解法参考:http://blog.csdn.net/dyx404514/article/details/9631787 刚学后缀自动机,还是有很多性质不是很了解……目前也就能做个模板题orz #include<cstdio> #include<cstring> #include<cstdlib> #include<algor…
The Little Elephant loves strings very much. He has an array a from n strings, consisting of lowercase English letters. Let's number the elements of the array from 1 to n, then let's denote the element number i as ai. For each string ai (1 ≤ i ≤ n) t…
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define maxn 18000001 using namespace std; char str[maxn]; int idx(char i) { if(i=='S') return 0; if(i=='N') return 1; if(i=='W') return 2; if(i=='E') retur…
here:https://oi-wiki.org/string/sam/ 下面转自 KesdiaelKen的雷蒻论坛 来个广义后缀自动机模板题 [USACO17DEC]Standing Out from the Herd #include <bits/stdc++.h> using namespace std; const int MAXN = 100005; int n, l[MAXN], m, s[MAXN]; long long ans[MAXN]; namespace SAM { co…
题意 给出n个字符串,问每个字符串中有多少子串是这所有的n个字符串中至少k个的子串. 分析 广义后缀自动机模板题.对这n个串建广义后缀自动机,对于每个状态维护两个值cou[u]和lcu[u]分别代表拥有这个状态的子串的数量和上一次更新到这个状态的子串的数量.然后设f[u]为状态u到祖先的所有结点有多少子串出现在至少k个字符串中.然后再跑一边每个子串就可以了. #include <cstdio> #include <cstring> #include <algorithm>…
Description Given two strings, you have to tell the length of the Longest Common Substring of them. For example:str1 = bananastr2 = cianaic So the Longest Common Substring is "ana", and the length is 3. Input The input contains several test case…