POJ 1509 Glass Beads【后缀自动机、最小表示法】

来源:互联网 发布:足球大数据分析 编辑:程序博客网 时间:2024/05/19 08:42

此题为最简单的后缀自动机的应用。

#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;}


原创粉丝点击