zoukankan      html  css  js  c++  java
  • SPOJ 1811 Longest Common Substring

    A string is finite sequence of characters over a non-empty finite set Σ.

    In this problem, Σ is the set of lowercase letters.

    Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.

    Now your task is simple, for two given strings, find the length of the longest common substring of them.

    Here common substring means a substring of two or more strings.

    Input

    The input contains exactly two lines, each line consists of no more than 250000 lowercase letters, representing a string.

    Output

    The length of the longest common substring. If such string doesn't exist, print "0" instead.

    Example

    Input:
    alsdfkjfjkdsal
    fdjskalajfkdsla
    
    Output:
    3
    

    题解:
    哈哈很意外啊,在电脑城随便找台机子用洛谷在线IDE 1A这题啊
    讲讲思路:
    以A建立SAM 让B在SAM上匹配
    可以类比于kmp思想,我们知道在Parent树上,fa是当前节点的子集,也就是说满足最大前缀,利用这个就可以做题了
    步骤如下:
    1.如果满足ch[p][c]存在,那么就直接走就是了,和AC自动机类似,len++
    2.如果不存在,那么就沿fa上跳,找到最大dis[fa]且满足存在c这个儿子的.类似于跳fail链
    3.跳到根就直接初始化,重新开始
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 const int N=550005;
     8 char S[N];int n=0,cnt=1,cur=1,last=1,ch[N][26],fa[N],dis[N];
     9 void build(int c){
    10     last=cur;cur=++cnt;dis[cur]=++n;
    11     int p=last;
    12     for(;p && !ch[p][c];p=fa[p])ch[p][c]=cur;
    13     if(!p)fa[cur]=1;
    14     else{
    15         int q=ch[p][c];
    16         if(dis[q]==dis[p]+1)fa[cur]=q;
    17         else{
    18             int nt=++cnt;dis[nt]=dis[p]+1;
    19             memcpy(ch[nt],ch[q],sizeof(ch[q]));
    20             fa[nt]=fa[q];fa[q]=fa[cur]=nt;
    21             for(;ch[p][c]==q;p=fa[p])ch[p][c]=nt;
    22         }
    23     }
    24 }
    25 int ans=0;
    26 void Flr()
    27 {
    28     int p=1,nxt,lt;
    29     scanf("%s",S);
    30     int l=strlen(S),len=0,c;
    31     for(int i=0;i<l;i++){
    32         c=S[i]-'a';
    33         if(ch[p][c]){
    34             len++;p=ch[p][c];
    35         }
    36         else{
    37             lt=0;nxt=0;
    38             while(p!=1){
    39                 if(ch[p][c] && dis[p]>lt)lt=dis[p],nxt=p;
    40                 p=fa[p];
    41             }
    42             if(nxt)
    43             p=ch[nxt][c],len=dis[nxt]+1;
    44             else
    45             p=1,len=0;
    46         }
    47         if(len>ans)ans=len;
    48     }
    49     printf("%d
    ",ans);
    50 }
    51 void work()
    52 {
    53     scanf("%s",S);
    54     for(int i=0,l=strlen(S);i<l;i++)build(S[i]-'a');
    55     Flr();
    56 }
    57 int main()
    58 {
    59     work();
    60     return 0;
    61 }
    
    
    
     
  • 相关阅读:
    [小技巧] micropython 如何执行 *.mpy 文件
    从零开始深入 Linux 底层(软件工程)
    从嵌套结构中取值时如何编写兜底逻辑
    学习JUC源码(2)——自定义同步组件
    学习JUC源码(1)——AQS同步队列(源码分析结合图文理解)
    Java多线程中的wait/notify通信模式
    详解Java锁的升级与对比(1)——锁的分类与细节(结合部分源码)
    认识Redis集群——Redis Cluster
    工作三年多的感慨与总结(二)
    工作三年多的感慨与总结(一)
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7273413.html
Copyright © 2011-2022 走看看