zoukankan      html  css  js  c++  java
  • SPOJ1811 LCS

    A string is finite sequence of characters over a non-empty finite set Σ.

    In this problem, Σ is the set of lowercase letters.

    Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.

    Now your task is simple, for two given strings, find the length of the longest common substring of them.

    Here common substring means a substring of two or more strings.

    Input

    The input contains exactly two lines, each line consists of no more than 250000 lowercase letters, representing a string.

    Output

    The length of the longest common substring. If such string doesn't exist, print "0" instead.

    Example

    Input:
    alsdfkjfjkdsal
    fdjskalajfkdsla
    
    Output:
    3
    

    Notice: new testcases added

    为什么都说这是后缀自动机的裸题啊。难道就我看不出来么qwq、、

    正解其实比较好想,先把第一个串扔到SAM里面

    对于第二个串依次枚举,如果能匹配就匹配,否则就沿着parent边走(怎么这么像AC自动机??),顺便记录一下最长长度

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN = 2 * 300000 + 1;
    char s1[MAXN], s2[MAXN];
    int N1, N2, tot = 1, root = 1, last = 1, len[MAXN], ch[MAXN][27], fa[MAXN];
    void insert(int x) {
        int now = ++tot, pre = last; last = now; len[now] = len[pre] + 1;
        for(; pre && !ch[pre][x]; pre = fa[pre]) ch[pre][x] = now;
        if(!pre) fa[now] = root;
        else {
            int q = ch[pre][x];
            if(len[q] == len[pre] + 1) fa[now] = q;
            else {
                int nows = ++tot; 
                memcpy(ch[nows], ch[q], sizeof(ch[q]));
                len[nows] = len[pre] + 1;
                fa[nows] = fa[q]; fa[now] = fa[q] = nows;
                for(; pre && ch[pre][x] == q; pre = fa[pre]) ch[pre][x] = nows;                
            }
        } 
    
    }
    int main() {
    #ifdef WIN32
        freopen("a.in", "r", stdin);
    #endif
        scanf("%s %s", s1 + 1, s2 + 1);
        N1 = strlen(s1 + 1); 
        N2 = strlen(s2 + 1);
        for(int i = 1; i <= N1; i++) 
            insert(s1[i] - 'a');
        int ans = 0, nowlen = 0, cur = root;
        for(int i = 1; i <= N2; i++, ans = max(ans, nowlen)) {
            int p = s2[i] - 'a';
            if(ch[cur][p]) {nowlen++, cur = ch[cur][p]; continue;}
            for(; cur && !ch[cur][p]; cur = fa[cur]);
            nowlen = len[cur] + 1, cur = ch[cur][p];
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    ExtJS专题(十):layout布局的使用(3)
    ExtJS专题(十一):lTree的Treepanel使用
    ExtJS专题(四):ExtJS组件的属性
    ExtJS专题(七):ExtJS面板Panel中视图区ViewPort的使用
    ExtJS专题(二):ExtJS类库和组件介绍
    ExtJS专题(十):layout布局的使用(1)
    EXtJS专题(九):ExtJS对话框的使用
    ExtJS专题(五):ExtJS面板Panel的使用
    ExtJS专题(三):ExtJS组件的使用
    ExtJS专题(八):ExtJS窗口Window的使用
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9233921.html
Copyright © 2011-2022 走看看