后缀自动机模板(SPOJ1811)

用后缀自动机实现求两个串的最长公共子串。

#include <cstdio>
#include <algorithm>

const int N = 500005;
char s[N];
int sz,sm,lst,ans,l[N],f[N],ch[N][26];

int main() {
    scanf("%s", s);
    for(int i = 0; s[i]; i++) {
        int c = s[i]-'a', u = lst;
        for(lst = ++sz, l[sz] = i+1; u && !ch[u][c]; u = f[u]) ch[u][c] = sz;
        int x = ch[u][c];
        if(!x) {ch[u][c] = sz; continue;}
        if(l[u]+1 == l[x]) {f[sz] = x; continue;}
        l[++sz] = l[u]+1, f[sz] = f[x], f[x] = f[lst] = sz;
        for(int j = 0; j < 26; j++) ch[sz][j] = ch[x][j];
        for(; u && ch[u][c] == x; u = f[u]) ch[u][c] = sz;
        if(ch[u][c] == x) ch[u][c] = sz;
    }
    scanf("%s", s);
    for(int i = 0, u = 0; s[i]; i++) {
        int c = s[i]-'a';
        for(; u && !ch[u][c]; sm=l[u=f[u]]);
        if(ch[u][c]) sm++, u = ch[u][c];
        ans = std::max(ans, sm);
    }
    printf("%d", ans);
    return 0;
}
posted @ 2016-12-15 12:02  Monster_Yi  阅读(191)  评论(0编辑  收藏  举报