• SPOJ LCS2


    LCS2 - Longest Common Substring II

    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 a bit harder, for some 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 at most 10 lines, each line consists of no more than 100000 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
    aaaajfaaaa
    
    Output:
    2
    

    求若干个字符串的最长公共子串。

    显然,如果是所有字符串的最长公共子串,至少得是第一个字符串的一个子串,所以对第一个字符串建后缀自动机,维护所有子串。然后把每个其他的字符串扔进去跑一边,找出来最远的公共点即可。

     1 #include <bits/stdc++.h>
     2 
     3 const int maxn = 1e6 + 5;
     4 
     5 /* AUTOMATON */
     6 
     7 int last;
     8 int tail;
     9 int mini[maxn];
    10 int maxi[maxn];
    11 int step[maxn];
    12 int fail[maxn];
    13 int next[maxn][26];
    14 
    15 inline void buildAutomaton(char *s)
    16 {
    17     last = 1; tail = 2;
    18     while (*s)
    19     {
    20         int c = *s++ - 'a';
    21         int p = last;
    22         int t = tail++;
    23         step[t] = step[p] + 1;
    24         mini[t] = maxi[t] = step[t];
    25         while (p && !next[p][c])
    26             next[p][c] = t, p = fail[p];
    27         if (p)
    28         {
    29             int q = next[p][c];
    30             if (step[q] == step[p] + 1)
    31                 fail[t] = q;
    32             else
    33             {
    34                 int k = tail++;
    35                 fail[k] = fail[q];
    36                 fail[q] = fail[t] = k;
    37                 step[k] = step[p] + 1;
    38                 mini[k] = maxi[k] = step[k];
    39                 memcpy(next[k], next[q], sizeof(next[k]));
    40                 while (p && next[p][c] == q)
    41                     next[p][c] = k, p = fail[p];
    42             }
    43         }
    44         else
    45             fail[t] = 1;
    46         last = t;
    47     }
    48 }
    49 
    50 inline void searchAutoMaton(char *s)
    51 {
    52     memset(maxi, 0, sizeof(maxi));
    53     for (int t = 1, k = 0; *s; )
    54     {
    55         int c = *s++ - 'a';
    56         if (next[t][c])
    57             ++k, t = next[t][c];
    58         else
    59         {
    60             while (t && !next[t][c])
    61                 t = fail[t];
    62             if (t)
    63                 k = step[t] + 1, t = next[t][c];
    64             else   
    65                 k = 0, t = 1;
    66         }
    67         if (maxi[t] < k)
    68             maxi[t] = k;
    69     }
    70     for (int i = tail - 1; i; --i)
    71         if (maxi[fail[i]] < maxi[i])
    72             maxi[fail[i]] = maxi[i];
    73     for (int i = 1; i < tail; ++i)
    74         if (mini[i] > maxi[i])
    75             mini[i] = maxi[i];
    76 }
    77 
    78 inline int calculate(void)
    79 {
    80     register int ret = 0;
    81     for (int i = 1; i < tail; ++i)
    82         if (ret < mini[i])
    83             ret = mini[i];
    84     return ret;
    85 }
    86 
    87 /* MAIN FUNC */
    88 
    89 char str[maxn];
    90 
    91 signed main(void)
    92 {
    93     scanf("%s", str);
    94     buildAutomaton(str);
    95     while (~scanf("%s", str))
    96         searchAutoMaton(str);
    97     printf("%d
    ", calculate());
    98 }

    @Author: YouSiki

  • 相关阅读:
    OpenSSH服务——密钥登录
    进程管理
    磁盘管理
    文件系统
    shell命令手册
    第一次常用命令手册
    远程连接mobaxterm安装使用
    Linux 系统CentOS 7 64 位安装
    PythonI/O进阶学习笔记_11.python的多进程
    PythonI/O进阶学习笔记_10.python的多线程
  • 原文地址:https://www.cnblogs.com/yousiki/p/6212629.html
Copyright © 2020-2023  润新知