POJ 1509 Glass Beads【后缀自动机、最小示意法】
POJ 1509 Glass Beads【后缀自动机、最小表示法】
此题为最简单的后缀自动机的应用。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn = 10010; struct SamNode { int ch[26]; int par, len; void Init() { par = -1; len = 0; memset(ch, -1, sizeof(ch)); } }; class SAM { public: void Init() { tot = 0; last = 0; sn[0].Init(); } void Add(int c) { int end = NewNode(); int tmp = last; sn[end].len = sn[last].len + 1; for ( ; tmp != -1 && sn[tmp].ch[c] == -1; tmp = sn[tmp].par) { sn[tmp].ch[c] = end; } if (tmp == -1) { sn[end].par = 0; } else { int nxt = sn[tmp].ch[c]; if (sn[tmp].len + 1 == sn[nxt].len) { sn[end].par = nxt; } else { int np = NewNode(); sn[np] = sn[nxt]; sn[np].len = sn[tmp].len + 1; sn[end].par = sn[nxt].par = np; for ( ; tmp != -1 && sn[tmp].ch[c] == nxt; tmp = sn[tmp].par) { sn[tmp].ch[c] = np; } } } last = end; } int tot; int last; SamNode sn[maxn*4]; int NewNode() { sn[++tot].Init(); return tot; } }; int t, n; char s[maxn]; SAM sam; int main() { scanf("%d", &t); while (t--) { scanf("%s", s); sam.Init(); n = strlen(s); for (int i = 0; i < n; ++i) { sam.Add(s[i] - 'a'); } for (int i = 0; i < n; ++i) { sam.Add(s[i] - 'a'); } int now = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < 26; ++j) { if (sam.sn[now].ch[j] != -1) { now = sam.sn[now].ch[j]; break; } } } printf("%d\n", sam.sn[now].len - n + 1); } return 0; }