2946: [Poi2000]公共串

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 787  Solved: 342
[Submit][Status][Discuss]

Description

 
       给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
任务:
l        读入单词
l        计算最长公共子串的长度
l        输出结果
 

Input

 
文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。
 

Output

仅一行,一个整数,最长公共子串的长度。
 

Sample Input

3
abcb
bca
acbc

Sample Output

HINT

Source

[Submit][Status][Discuss]

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

和SPOJ的那道题简直一模一样,后缀自动机。

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

@Author: YouSiki

BZOJ 2946: [Poi2000]公共串的更多相关文章

  1. BZOJ 2946: [Poi2000]公共串( 后缀自动机 )

    一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...

  2. bzoj 2946 [Poi2000]公共串——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946 对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走 ...

  3. BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)

    求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...

  4. BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

    题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...

  5. BZOJ 2946 [Poi2000]公共串 ——后缀自动机

    任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...

  6. bzoj 2946: [Poi2000]公共串【SAM】

    对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会 ...

  7. 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)

    2946: [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1063  Solved: 469 Description      ...

  8. 【BZOJ】2946: [Poi2000]公共串

    http://www.lydsy.com/JudgeOnline/problem.php?id=2946 题意:给n个串,求最大公共子串.(1<=n<=5,每个串长度<=2000) ...

  9. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

随机推荐

  1. iOS真机测试碰到错误linker command failed with exit code 1 (use -v to see invocation)

    在模拟器上运行正常,但是在模拟器上就会报错,这是因为xocde7之后增加了一个bitcode,bitcode是被编译程序的一种中间形式的代码.包含bitcode配置的程序将会在App store上被编 ...

  2. iOS-多线程之GCD(原创)

    前言 GCD 全称 Grand Central DisPath NSOperation便是基于GCD的封装 基础知识 1.GCD的优势 (1)为多核的并行运算提出了解决方案 (2)GCD会自动利用更多 ...

  3. fragment 监听返回

    @Override public void onResume() { super.onResume(); getView().setFocusableInTouchMode(true); getVie ...

  4. Linux系统VNC配置实践总结

    VNC概述 VNC (Virtual Network Computing)是虚拟网络计算机的缩写.VNC 是一款优秀的远程控制工具软件,由著名的 AT&T 的欧洲研究实验室开发的.VNC 是在 ...

  5. ComboBox(下拉列表框)实现省、市、县三级联动,用hibernate连接数据库

    package com.hanqi.web; import java.io.IOException; import java.util.List; import javax.servlet.Servl ...

  6. 关于Java中枚举Enum的深入剖析

    在编程语言中我们,都会接触到枚举类型,通常我们进行有穷的列举来实现一些限定.Java也不例外.Java中的枚举类型为Enum,本文将对枚举进行一些比较深入的剖析. 什么是Enum Enum是自Java ...

  7. MYSQL 5.7 无法启动(Could not open error log file errno 2)

    前两天电脑中毒, 病毒好像把mysql的 log.err 文件给删掉了.然后服务一直启动不了:Could not open error log file errno 2. 然后疯狂百度,搜索的结果大多 ...

  8. 【转】关于Java的Daemon线程的理解

    原文地址:http://www.cnblogs.com/ChrisWang/archive/2009/11/28/1612815.html 关于Java的Daemon线程的理解 网上对Java的Dae ...

  9. Python字符串str的方法使用

    #!usr/bin/env python# -*-coding:utf-8-*-#字符串通常用双引号或单引号来表示:'123',"abc","字符串"#str字 ...

  10. C# 扩展方法集

    语法注意点 可以使用扩展方法来扩展类或接口. 不能重写扩展方法. 扩展方法只能在非嵌套.非泛型静态类内部定义. 扩展方法必须定义在静态类中. 扩展方法的第一个参数的类型用于指定被扩展的类型,它限制该扩 ...