zoukankan      html  css  js  c++  java
  • SP1811 【LCS

    (SAM)上匹配

    我们就是需要找到两个串的最长公共子串

    先对其中一个串建出(SAM),之后我们把另一个串放到上面跑

    如果当前在(SAM)的状态是(now),下一个字符是(c),匹配出的的长度为(L)

    • 如果(now)(c)这个转移,我们就转移过去,(L)++

    • 如果没有我们就跳(link),知道跳到有这个转移为止,同时把(L)搞成新状态的(len)

    这样做就好了

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define LL long long
    #define maxn 500005
    #define max(a,b) ((a)>(b)?(a):(b))
    char S[maxn>>1],T[maxn>>1];
    int lst=1,n,m,len[maxn],pre[maxn],son[maxn][26];
    int now=1,L,ans,cnt=1;
    inline void ins(int c)
    {
        int f=lst,p=++cnt; lst=p;
        len[p]=len[f]+1;
        while(f&&!son[f][c]) {son[f][c]=p;f=pre[f];}
        if(!f) {pre[p]=1;return;}
        int x=son[f][c];
        if(len[f]+1==len[x]) {pre[p]=x;return;}
        int y=++cnt;
        len[y]=len[f]+1;pre[y]=pre[x];pre[x]=pre[p]=y;
        for(int i=0;i<26;i++) son[y][i]=son[x][i];
        while(f&&son[f][c]==x) {son[f][c]=y;f=pre[f];}
    }
    inline void q(int c)
    {
        if(son[now][c]) {now=son[now][c];L++;ans=max(ans,L);return;}
        while(now&&!son[now][c]) now=pre[now];
        if(!now) {now=1,L=0;return;}
        L=len[now]+1;now=son[now][c];ans=max(ans,L);
    }
    int main()
    {
        scanf("%s",S+1);n=strlen(S+1);
        for(int i=1;i<=n;i++) ins((int)(S[i]-'a'));
        scanf("%s",T+1);n=strlen(T+1);
        for(int i=1;i<=n;i++) q((int)(T[i]-'a'));
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    .net注册iis
    hdu 1081To The Max
    hdu 1312Red and Black
    hdu 1016Prime Ring Problem
    hdu 1159Common Subsequence
    hdu 1372Knight Moves
    hdu 1686Oulipo
    hdu 1241Oil Deposits
    hdu 1171Big Event in HDU
    hdu 4006The kth great number
  • 原文地址:https://www.cnblogs.com/asuldb/p/10217082.html
Copyright © 2011-2022 走看看