zoukankan      html  css  js  c++  java
  • 后缀自动机 (SAM)

    后缀自动机

    #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;
    }
    
  • 相关阅读:
    浏览器嗅探
    (转)javascript中为何在匿名function函数后面还外加一个括号
    js十进制转换二进制
    css_毛玻璃
    css桌布样式
    ocr api 识别表格 图片
    Linux查看日志常用命令
    linux find 命令查找文件和文件夹
    docker上安装airflow
    文件权限中 chmod、u+x、u、r、w、x分别代表什么
  • 原文地址:https://www.cnblogs.com/shawk/p/14183190.html
Copyright © 2011-2022 走看看