zoukankan      html  css  js  c++  java
  • codevs 3160 最长公共子串(SAM)

    3160 最长公共子串

     
    题目描述 Description

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

    输入描述 Input Description

    读入两个字符串

    输出描述 Output Description

    输出最长公共子串的长度

    样例输入 Sample Input
    yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
    yeaphowmuchiloveyoumydearmother
    样例输出 Sample Output

    27

    数据范围及提示 Data Size & Hint

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

    【思路】

      SAM求LCS

    【代码】

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 
     5 const int N = 2*1e5+10;
     6 
     7 char s[N];
     8 int sz,root,last,fa[N],ch[N][26],l[N],n;
     9 
    10 void add(int x) {
    11     int c=s[x]-'a';
    12     int p=last,np=++sz; last=np;
    13     l[np]=x+1;
    14     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    15     if(!p) fa[np]=root;
    16     else {
    17         int q=ch[p][c];
    18         if(l[p]+1==l[q]) fa[np]=q;
    19         else {
    20             int nq=++sz; l[nq]=l[p]+1;
    21             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    22             fa[nq]=fa[q];
    23             fa[np]=fa[q]=nq;
    24             for(;p&&q==ch[p][c];p=fa[p]) ch[p][c]=nq;
    25         }
    26     }
    27 }
    28 void build() {
    29     root=last=++sz;
    30     scanf("%s",s);
    31     n=strlen(s);
    32     for(int i=0;i<n;i++) add(i);
    33 }
    34 void lcs() {
    35     scanf("%s",s);
    36     n=strlen(s);
    37     int p=root,ans=0,len=0;
    38     for(int i=0;i<n;i++) {
    39         int c=s[i]-'a';
    40         if(ch[p][c]) { len++; p=ch[p][c]; }
    41         else {
    42             for(;p&&!ch[p][c];p=fa[p]);
    43             if(!p) { p=root; len=0; }
    44             else {
    45                 len=l[p]+1; p=ch[p][c];
    46             }
    47         }
    48         if(len>ans) ans=len;
    49     }
    50     printf("%d",ans);
    51 }
    52 
    53 int main() {
    54     build();
    55     lcs();
    56     return 0;
    57 }
  • 相关阅读:
    [数据结构]图的DFS和BFS的两种实现方式
    [算法]两个栈实现一个队列
    [数据结构]手动实现队列
    [数据结构]手动实现栈
    [数据结构]手动实现单链表
    Hive分组取Top K数据
    HBase解决海量图片存储方案
    非结构化数据存储方案
    头条面试题之实现两个线程轮流打印字符串
    [算法]最大连续子数组和,最长重复子串,最长无重复字符子串
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5199214.html
Copyright © 2011-2022 走看看