后缀自动机 (SAM)

摘要:
后缀自动机#include<csdio>#包括<cstring>#包括<算法>组成N=2e6+5;结构边缘{intn,t;}e[N];其中[N],edc;voidAdd(intx,inty){e[++edc]=(边){h[x],y};h[x]=edc;}结构树{intf,c[26
后缀自动机
#include <cstdio>
#include <cstring>
#include <algorithm>

const int N = 2e6 + 5;

struct Edge {
    int n, t;
}e[N];
int h[N], edc;

void Add(int x, int y) {
    e[++edc] = (Edge) {h[x], y}; h[x] = edc;
}

struct Tree {
    int f, c[26];
}t[N];

int n, sz[N], len[N], lt, trc, ans;
char s[N];

void Dfs(int x) {
    for (int i = h[x], y; i; i = e[i].n)
        Dfs(y = e[i].t), sz[x] += sz[y];
    if (sz[x] > 1) ans = std::max(ans, sz[x] * len[x]);
}

int main() {
    scanf("%s", s + 1);
    n = strlen(s + 1);
    lt = trc = 1;
    for (int i = 1; i <= n; ++i) {
        int x = lt, c = s[i] - 'a', y, z;
        len[lt = ++trc] = len[x] + 1; sz[lt] = 1;
        for (; x && !t[x].c[c]; x = t[x].f) t[x].c[c] = lt;
        if (!x) t[lt].f = 1;
        else if (len[y = t[x].c[c]] == len[x] + 1) t[lt].f = y;
        else {
            t[z = ++trc] = t[y]; len[z] = len[x] + 1;
            t[y].f = t[lt].f = z;
            for (; x && t[x].c[c] == y; x = t[x].f) t[x].c[c] = z;
        }
    }
    for (int i = 2; i <= trc; ++i)
        Add(t[i].f, i);
    Dfs(1);
    printf("%d
", ans);
    return 0;
}
广义后缀自动机
#include <cstdio>
#include <cstring>

const int N = 2e6 + 5;

struct Sam {
    int f, s[26];
}t[N];
int m, n, len[N], trc = 1;
long long ans;
char s[N];

int main() {
    scanf("%d", &m);
    while (m--) {
        scanf("%s", s + 1);
        int rt = 1, n = strlen(s + 1);
        for (int i = 1; i <= n; ++i) {
            int x = rt, c = s[i] - 'a', y;
            if (t[x].s[c] && len[rt = y = t[x].s[c]] > len[x] + 1) {
                t[rt = ++trc] = t[y]; len[trc] = len[x] + 1; t[y].f = trc;
                for (; x && t[x].s[c] == y; x = t[x].f) t[x].s[c] = trc;
            }
            else {
                len[rt = ++trc] = len[x] + 1;
                for (; x && !t[x].s[c]; x = t[x].f) t[x].s[c] = rt;
                if (!x) t[rt].f = 1;
                else if (len[y = t[x].s[c]] == len[x] + 1) t[rt].f = y;
                else {
                    t[++trc] = t[y]; len[trc] = len[x] + 1; t[rt].f = t[y].f = trc;
                    for (; x && t[x].s[c] == y; x = t[x].f) t[x].s[c] = trc;
                }
            }
        }
    }
    for (int i = 2; i <= trc; ++i)
        ans += len[i] - len[t[i].f];
    printf("%lld
", ans);
    return 0;
}

免责声明:文章转载自《后缀自动机 (SAM)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇easyui tab 关闭php中浮点数计算问题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章