zoukankan      html  css  js  c++  java
  • SPOJ

    LCS - Longest Common Substring

    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


    题意:

      求两个串的最长公共子串。

    题解:

      先用第一个串构造出后缀自动机,然后逐个的匹配第二个串

      如果当前节点失配,利用Suffix Links 往后跳就可以了。

    #include <bits/stdc++.h>
    inline long long read(){long long x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
    using namespace std;
    
    const int N = 3e5+7;
    
    const long long mod = 1000000007;
    
    int isPlus[N * 2],endpos[N * 2];int d[N * 2];
    int tot,slink[2*N],trans[2*N][28],minlen[2*N],maxlen[2*N],pre;
    int newstate(int _maxlen,int _minlen,int* _trans,int _slink){
        maxlen[++tot]=_maxlen;minlen[tot]=_minlen;
        slink[tot]=_slink;
        if(_trans)for(int i=0;i<26;i++)trans[tot][i]=_trans[i],d[_trans[i]]+=1;
        return tot;
    }
    int add_char(char ch,int u){
        int c=ch-'a',v=u;
        int z=newstate(maxlen[u]+1,-1,NULL,0);
        isPlus[z] = 1;
        while(v&&!trans[v][c]){trans[v][c]=z;d[z]+=1;v=slink[v];}
        if(!v){ minlen[z]=1;slink[z]=1;return z;}
        int x=trans[v][c];
        if(maxlen[v]+1==maxlen[x]){slink[z]=x;minlen[z]=maxlen[x]+1;return z;}
        int y=newstate(maxlen[v]+1,-1,trans[x],slink[x]);
        slink[z]=slink[x]=y;minlen[x]=minlen[z]=maxlen[y]+1;
        while(v&&trans[v][c]==x){trans[v][c]=y;d[x]--,d[y]++;v=slink[v];}
        minlen[y]=maxlen[slink[y]]+1;
        return z;
    }
    void init_sam() {
        for(int i = 1; i <= tot; ++i)
            for(int j = 0; j < 26; ++j) trans[i][j] = 0;
        pre = tot = 1;
    }
    char a[N],b[N];
    int main() {
        scanf("%s%s",a,b);
        init_sam();
        int n = strlen(a);
        int m = strlen(b);
        for(int i = 0; i < n; ++i)
            pre = add_char(a[i],pre);
        int ans = 0;
        int now = 1;
        int sum = 0;
        for(int i = 0; i < m; ++i) {
            if(trans[now][b[i]-'a']) {
                now = trans[now][b[i]-'a'];
            } else {
                while(now) {
                    now = slink[now];
                    if(trans[now][b[i]-'a']) break;
                }
                if(!now) now = 1,sum = 0;
                else {
                    if(trans[now][b[i]-'a']) {
                        sum = maxlen[now] + 1;
                        now = trans[now][b[i]-'a'];
                    }
                }
            }
            ans = max(ans,sum);
        }
        printf("%d
    ",ans);
    }
  • 相关阅读:
    免费下载 80多种的微软推出入门级 .NET视频
    和付费网盘说再见,自己搭建个人网盘(Java 开源项目)
    JS惰性删除和定时删除可过期的localStorage缓存,或sessionStorage缓存
    docker——系列文章
    Bash 脚本教程
    Sublime text3里 修改TAB键为缩进为四个空格
    百度网盘不限速,直接获取直链
    技术党适合做浏览器首页的网站
    常用电脑软件
    有哪些开源的 Python 库让你相见恨晚?
  • 原文地址:https://www.cnblogs.com/zxhl/p/7616318.html
Copyright © 2011-2022 走看看