zoukankan      html  css  js  c++  java
  • LCS

    SP1811 LCS - Longest Common Substring

    用 sam 进行字符串匹配,建 s 的 sam,然后用 t 在 s 的 sam 上进行匹配,匹配过程中,沿着 Next 转移往下走,如果失配,则沿着 link 链接往上跳,因为 link 链接是该节点的后缀,所以这样跳就不会有遗漏,而且均摊下来跳后缀链接的总复杂度为(O(n))因此不会超时。

    // Created by CAD
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=(2e5+5e4+5)*2;
    namespace sam{
        int len[maxn],link[maxn],Next[maxn][26];
        int sz,last;
        void init(){                //记得初始化
            sz=last=0;
            len[0]=0,link[0]=-1;
        }
        void insert(char c){        //插入字符
            int now=++sz;
            len[now]=len[last]+1;
            int p=last;
            while(~p&&!Next[p][c-'a']){
                Next[p][c-'a']=now;
                p=link[p];
            }
            if(p==-1) link[now]=0;
            else{
                int q=Next[p][c-'a'];
                if(len[p]+1==len[q]) link[now]=q;
                else{
                    int clone=++sz;
                    len[clone]=len[p]+1;
                    memcpy(Next[clone],Next[q],sizeof(Next[q]));
                    link[clone]=link[q];
                    while(~p&&Next[p][c-'a']==q){
                        Next[p][c-'a']=clone;
                        p=link[p];
                    }
                    link[q]=link[now]=clone;
                }
            }
            last=now;
        }
        int solve(char *s,char *t){
            int ans=0;
            int op=0,last=-1;
            int slen=strlen(s),tlen=strlen(t);
            int now=0;
            while(op<tlen){
                int temp=0;
                while(op<tlen&&Next[now][t[op]-'a']){//如果匹配则沿着转移走下去
                    now=Next[now][t[op]-'a'];
                    temp=op-last;
                    ans=max(ans,temp);
                    op++;
                }
                if(temp==0) op++,last++;
                while(~link[now]&&!Next[now][t[op]-'a'])
                    //一旦失配,则沿着后缀链接往上跳,直到跳到0或者再次匹配
                    now=link[now];
                	last+=temp-len[now];
            }
            return ans;
        }
    }
    
    char s[maxn],t[maxn];
    int main() {
        sam::init();
        scanf("%s%s",s,t);
        int slen=strlen(s);
        for(int i=0;i<slen;++i) sam::insert(s[i]);
        printf("%d
    ",sam::solve(s,t));
        return 0;
    }
    
  • 相关阅读:
    Shiro结合配置文件实战实现权限验证
    Shiro的一些概念解释以及配置了解
    jedis工具类
    【转载】redis的主从复制
    Redis的事务
    redis的持久化
    SSM框架-SpringMVC 实例文件上传下载
    如何设置CentOS 7获取动态及静态IP地址
    阿里云linux centos 一键部署web环境--图文详解
    SVN使用教程总结
  • 原文地址:https://www.cnblogs.com/CADCADCAD/p/13529276.html
Copyright © 2011-2022 走看看