【Codevs3160】最长公共子串

当然先虐SAM裸题QwQ
3160 最长公共子串

时间限制: 2 s
空间限制: 128000 KB
题目等级 : 大师 Master

题目描述 Description

给出两个由小写字母组成的字符串,求它们的最长公共子串的长度。
输入描述 Input Description

读入两个字符串
输出描述 Output Description

输出最长公共子串的长度
样例输入 Sample Input

yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother

样例输出 Sample Output

27
数据范围及提示 Data Size & Hint

单个字符串的长度不超过100000

对第一个串建好SAM把第二个串放进SAM运行就好了.随时记录一下当前匹配子串的长度最后取max.
在build函数和solve函数里循环终止条件一开始没用l竟然跑了3000msQAQ
用l取代之后只有89ms_(:зゝ∠)_
注意给SAM的变量多开点,因为状态数和转移数并不是只有n个的…有一些多余的.一开始脑残了只开了 105 RE不止.

#include
#include
#include
#include
#include
#define MAXN 200010
#define MAXINT 0x7fffffff
using namespace std;
int ans;
char ch[MAXN];
struct sam
{
    int last,cnt,p,q,np,nq;
    int a[MAXN][26],len[MAXN],fa[MAXN];
    sam()
    {
        last = ++cnt;
    }
    void insert(int c)
    {
        p = last;np = last = ++cnt;len[np] = len[p] + 1;
        while (!a[p][c] && p)   a[p][c] = np,p = fa[p];
        if (!p) fa[np] = 1;
        else
        {
            q = a[p][c];
            if (len[p] + 1 == len[q])   fa[np] = q;
            else
            {
                nq = ++cnt;len[nq] = len[p] + 1;
                memcpy(a[nq],a[q],sizeof(a[q]));
                fa[nq] = fa[q];
                fa[np] = fa[q] = nq;
                while (a[p][c] == q)    a[p][c] = nq,p = fa[p];
            }
        }
    }
    void build()
    {
        scanf("%s",ch+1);
        int l=strlen(ch+1);
        for (int i = 1;i <= l;i++)  insert(ch[i] - 'a');
    }
    void solve()
    {
        scanf("%s",ch+1);
        int tmp = 0,l=strlen(ch+1);
        for (int i = 1;i <= l;i++)
        {
            int c = ch[i] - 'a';
            if (a[p][c])    p = a[p][c],tmp++;
            else
            {
                while (p && !a[p][c])   p = fa[p];
                if (!p) p = 1,tmp = 0;
                else    tmp = len[p] + 1,p = a[p][c];
            }
            ans = max(ans,tmp);
        }
    }
}sam;
int main()
{
    sam.build();
    sam.solve();
    printf("%d",ans);
}

你可能感兴趣的:(随便搞搞,模板题库)