SPOJ – LCS Longest Common Substring 后缀自动机

ProLightsfx 2017-3-4 127 3/4

Longest Common Substring 后缀自动机

Source
SPOJ - LCS

My Solution
题意:求两个字符串的最长公共子串。
后缀自动机
看了很久 WJMZBMR 讲后缀自动机的ppt才大致把后缀自动机搞懂^_^,
此外附上两个比较好的讲后缀自动机的博客 后缀自动机 模版后缀自动机讲解
这题直接用一个字符串建立后缀自动机,然后用另一个串在自动机上跑即可,操作和AC自动机有点类似,
只是AC自动机匹配失败的时候用的fail指针,而这里用pre树跳转。
复杂度 O(n)
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
const int maxn = 2*2.5e5 + 8;

string s;
struct SAM{
    int ch[maxn][26], pre[maxn], val[maxn];
    int last, tot;
    void init(){
        last = tot = 0;
        memset(ch[0], -1, sizeof ch[0]);
        pre[0] = -1; val[0] = 0;
    }
    void extend(int c){
        int p = last, np = ++tot;
        val[np] = val[p] + 1;
        memset(ch[np], -1, sizeof ch[np]);
        while(~p && ch[p][c] == -1) ch[p][c] = np, p = pre[p];
        if(p == -1) pre[np] = 0;
        else{
            int q = ch[p][c];
            if(val[q] != val[p] + 1){
                int nq = ++tot;
                memcpy(ch[nq], ch[q], sizeof ch[q]);
                val[nq] = val[p] + 1;
                pre[nq] = pre[q];
                pre[q] = pre[np] = nq;
                while(~p && ch[p][c] == q) ch[p][c] = nq, p = pre[p];
            }
            else pre[np] = q;
        }
        last = np;
    }
    int _find(const string &s){
        int sz = s.size(), u = 0, tmp = 0, c, i, res = 0;
        for(i = 0; i < sz; i++){ c = s[i] - 'a'; if(~ch[u][c]) tmp++, u = ch[u][c]; else{ while(~u && ch[u][c] == -1) u = pre[u]; if(~u) tmp = val[u] + 1, u = ch[u][c]; else tmp = 0, u = 0; } res = max(res, tmp); } return res; } } sam; int main() { #ifdef LOCAL freopen("11.in", "r", stdin); //freopen("11.out", "w", stdout); int T = 2; while(T--){ #endif // LOCAL ios::sync_with_stdio(false); cin.tie(0); int n, i; cin >> s;
    n = s.size();
    sam.init();
    for(i = 0; i < n; i++) sam.extend(s[i] - 'a'); cin >> s;
    cout << sam._find(s) << endl;;


    #ifdef LOCAL
    cout << endl;
    }
    #endif // LOCAL
    return 0;
}

 


非特殊说明,本博所有文章均为博主原创,未经许可不得转载。

https://www.prolightsfxjh.com/

Thank you!

                                                                                                                                             ------from ProLightsfx

 

- THE END -

ProLightsfx

11月15日18:40

最后修改:2024年11月15日
0

非特殊说明,本博所有文章均为博主原创,未经许可不得转载。

共有 0 条评论