后缀自动机模板 SAM
一点疑问:
当创建nq节点时,要不要把nq的cnt标记赋值为1?
讲道理nq节点也是代表一个子串啊,不过网上的模板都没赋值。
2017.9.18 update:
把memset部分重写,改成用节点用到时再初始化,初始化所有节点可能被卡。
fa,len,cnt数组其实不用清空,因为用时都赋值了。
struct SAM { static const int MAXN = 300001<<1;//大小为字符串长度两倍 static const int LetterSize = 26; int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN]; int sum[MAXN], tp[MAXN], cnt[MAXN]; //sum,tp用于拓扑排序,tp为排序后的数组 void init( void) { last = tot = 1; len[1] = 0; memset( ch[1], 0, sizeof ch[1]); } void add( int x) { int p = last, np = last = ++tot; len[np] = len[p]+ 1, cnt[last] = 1; memset( ch[np], 0, sizeof ch[np]); while( p && !ch[p][x]) ch[p][x] = np, p = fa[p]; if( p == 0) fa[np] = 1; else { int q = ch[p][x]; if( len[q] == len[p] + 1) fa[np] = q; else { int nq = ++tot; memcpy( ch[nq], ch[q], sizeof ch[q]); len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq; while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p]; } } } void toposort( void) { for(int i = 1; i <= len[last]; i++) sum[i] = 0; for(int i = 1; i <= tot; i++) sum[len[i]]++; for(int i = 1; i <= len[last]; i++) sum[i] += sum[i-1]; for(int i = 1; i <= tot; i++) tp[sum[len[i]]--] = i; for(int i = tot; i; i--) cnt[fa[tp[i]]] += cnt[tp[i]]; } } sam;
- SAM(后缀自动机)模板
- 后缀自动机,SAM,suffix automaton 模板
- 后缀自动机(SAM)模板
- 后缀自动机(SAM)模板
- Sam后缀自动机模板
- 【模板整合】SAM后缀自动机的构建
- 浅谈后缀自动机SAM
- codeforces 235 C Cyclical Quest (后缀自动机 SAM)
- [后缀自动机 模板题] SPOJ 1812 Longest Common Substring II & BZOJ 2946 [Poi2000]公共串
- 后缀自动机模板题
- SPOJ 8222. Substrings(后缀自动机模板)
- HDU 4436 str2int (后缀自动机SAM,多串建立)
- 洛谷3804:【模板】后缀自动机——题解
- HDU 4270 SAM 后缀自动机
- [SAM] hihoCoder1445 后缀自动机二·重复旋律5
- spoj 1811 LCS (后缀自动机 SAM)
- codeforces 127D Password (后缀自动机 SAM)
- 回文(后缀)自动机模板
- [后缀自动机 模板题] SPOJ 8222 Substrings
- 后缀自动机模板 洛谷p3804