hihoCoder #1445 : 后缀自动机二·重复旋律5
2016-12-23 15:12
477 查看
#1445 : 后缀自动机二·重复旋律5
时间限制:10000ms单点时限:2000ms
内存限制:256MB
描述
小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为一段数构成的数列。现在小Hi想知道一部作品中出现了多少不同的旋律?
解题方法提示
输入
共一行,包含一个由小写字母构成的字符串。字符串长度不超过 1000000。输出
一行一个整数,表示答案。样例输入
aab
样例输出
5
后缀自动机,学习了最短路的转移。
/************************************************************************* > File: main.cpp > Author: You Siki > Mail: You.Siki@outlook.com > Time: 2016年12月23日 星期五 14时25分55秒 ************************************************************************/ #include<bits/stdc++.h> //using namespace std; const int maxn = 2000005; /* AUTOMATON */ int last = 1; int tail = 2; int step[maxn]; int fail[maxn]; int mini[maxn]; int next[maxn][26]; inline void buildAutomaton(char *s) { while (*s) { int p = last; int t = tail++; int c = *s++ - 'a'; step[t] = step[p] + 1; while (p && !next[p][c]) next[p][c] = t, p = fail[p]; if (p) { int q = next[p][c]; if (step[q] == step[p] + 1) fail[t] = q, mini[t] = step[q] + 1; else { int k = tail++; fail[k] = fail[q]; fail[q] = fail[t] = k; step[k] = step[p] + 1; mini[q] = step[k] + 1; mini[t] = step[k] + 1; for (int i = 0; i < 26; ++i) next[k][i] = next[q][i]; while (p && next[p][c] == q) next[p][c] = k, p = fail[p]; mini[k] = step[fail[k]] + 1; } } else fail[t] = 1, mini[t] = 1; last = t; } } inline long long solve(void) { long long ret = 0; for (int i = 2; i < tail; ++i) ret += step[i] - mini[i] + 1; return ret; } /* MAIN FUNC */ char str[maxn]; signed main(void) { scanf("%s", str); buildAutomaton(str); printf("%lld\n", solve()); }
20170222 复习SAM模板
#include <cstdio> #include <cstring> const int siz = 2000005; int last = 1; int tail = 2; int mini[siz]; int maxi[siz]; int fail[siz]; int next[siz][26]; inline void build(char *s) { while (*s) { int p = last; int t = tail++; int c = *s++ - 'a'; maxi[t] = maxi[p] + 1; while (p && !next[p][c]) next[p][c] = t, p = fail[p]; if (p) { int q = next[p][c]; if (maxi[q] == maxi[p] + 1) fail[t] = q, mini[t] = maxi[q] + 1; else { int k = tail++; fail[k] = fail[q]; fail[t] = fail[q] = k; maxi[k] = maxi[p] + 1; mini[q] = maxi[k] + 1; mini[t] = maxi[k] + 1; mini[k] = maxi[fail[k]] + 1; memcpy(next[k], next[q], 26 * sizeof(int)); while (next[p][c] == q) next[p][c] = k, p = fail[p]; } } else fail[t] = 1, mini[t] = 1; last = t; } } inline void calc(void) { long long ans = 0; for (int i = 2; i < tail; ++i) ans += maxi[i] - mini[i] + 1; printf("%lld\n", ans); } signed main(void) { static char s[siz]; scanf("%s", s); build(s); calc(); }
View Code
@Author: YouSiki
相关文章推荐
- hihocoder #1445 : 后缀自动机二·重复旋律5
- hihocoder #1445 : 后缀自动机二·重复旋律5
- 【后缀自动机】hihocoder1445 后缀自动机二·重复旋律5
- HihoCoder - 1445 后缀自动机二·重复旋律5 后缀自动机
- 【hihocoder1445】后缀自动机二·重复旋律5 后缀自动机模板
- hiho一下第130周 后缀自动机二·重复旋律7
- HihoCoder1445 重复旋律5(后缀自动机)
- [SAM] hihoCoder1445 后缀自动机二·重复旋律5
- hihocoder #1449 : 后缀自动机三·重复旋律6
- hiho一下第129周 后缀自动机二·重复旋律6
- hihocoder 1445 : 后缀自动机二·重复旋律5(后缀自动机)
- hihocoder #1457 : 后缀自动机四·重复旋律7
- hihocoder #1465 : 后缀自动机五·重复旋律8
- hiho一下第131周 后缀自动机二·重复旋律8(循环相似子串)
- hihocoder1445 后缀自动机二·重复旋律5
- hiho一下第128周 后缀自动机二·重复旋律5
- hihocold #1466 : 后缀自动机六·重复旋律9
- 【后缀自动机】【拓扑排序】【动态规划】hihocoder1457 后缀自动机四·重复旋律7
- 【hihocoder1457】后缀自动机四·重复旋律7 后缀自动机
- BZOJ 后缀自动机四·重复旋律7