菜鸡万年更博。

全是菜题。

 

SP1811 LCS - Longest Common Substring

对一个串建立自动机,另一个串在自动机上遍历,失配时跳father更新即可。ans=遍历到的点的len的最大值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define lb lower_bound
#define ub upper_bound
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;

inline int read()
{
    char c=getchar();int num=0,f=1;
    for(;!isdigit(c);c=getchar())
        f=c=='-'?-1:f;
    for(;isdigit(c);c=getchar())
        num=num*10+c-'0';
    return num*f;
}

const int N=25e4+3;

char S[N],T[N];

struct SAM
{
    int ch[26],fa,len;
}sam[N<<1];

int tot=1,lst=1;
void insert(int x)
{
    int p=lst;lst=++tot;sam[lst].len=sam[p].len+1;
    for(;p&&!sam[p].ch[x];p=sam[p].fa) sam[p].ch[x]=lst;
    if(!p) sam[lst].fa=1;
    else
    {
        int q=sam[p].ch[x];
        if(sam[p].len+1==sam[q].len) sam[lst].fa=q;
        else
        {
            int nq=++tot;sam[nq]=sam[q],sam[nq].len=sam[p].len+1;
            sam[lst].fa=sam[q].fa=nq;
            for(;sam[p].ch[x]==q;p=sam[p].fa) sam[p].ch[x]=nq;
        }
    }
}

int main()
{
    scanf("%s%s",S+1,T+1);
    for(int i=1;S[i];++i) insert(S[i]-'a');
    int now=1,len=0,Ans=0;
    for(int i=1;T[i];++i)
    {
        T[i]-='a';
        if(sam[now].ch[T[i]]) ++len,now=sam[now].ch[T[i]];
        else
        {
            while(now&&!sam[now].ch[T[i]]) now=sam[now].fa;
            if(!now) now=1,len=0;
            else len=sam[now].len+1,now=sam[now].ch[T[i]];
        }
        Ans=max(Ans,len);
    }
    cout<<Ans;
    return 0;
}
View Code

相关文章: