\(\color{Red}{Link}\)

\(\text{Solution:}\)

还是\(\text{Suffix Tree.}\)

根据\(\color{Blue}{Link}\)我们可以得到一个普适性较强的做法。

而这题就是多组数据。改下数据即可。

但是字符串的输入要绝对注意,每一次的清空都不能落下。

  1. #include<bits/stdc++.h>
  2. #include<ctime>
  3. using namespace std;
  4. const int MAXN=2e6+10;
  5. char Z[20][100001];
  6. int n,val[MAXN],ans,M,num,Case;
  7. int sum[20][MAXN];
  8. const int inf=(1<<30);
  9. struct SuffixTree {
  10. int link[MAXN],ch[MAXN][50],now,rem,n;
  11. int start[MAXN],len[MAXN],tail,s[MAXN];
  12. SuffixTree() {
  13. tail=now=1;
  14. rem=n=0;
  15. len[0]=inf;
  16. }
  17. inline int build(int a,int b) {
  18. link[++tail]=1;
  19. start[tail]=a;
  20. len[tail]=b;
  21. return tail;
  22. }
  23. void Extend(int x) {
  24. s[++n]=x;
  25. ++rem;
  26. for(int last=1; rem;) {
  27. while(rem>len[ch[now][s[n-rem+1]]])
  28. rem-=len[now=ch[now][s[n-rem+1]]];
  29. int &v=ch[now][s[n-rem+1]];
  30. int c=s[start[v]+rem-1];
  31. if(!v||x==c) {
  32. link[last]=now;
  33. last=now;
  34. if(!v)v=build(n,inf);
  35. else break;
  36. } else {
  37. int u=build(start[v],rem-1);
  38. ch[u][c]=v;
  39. ch[u][x]=build(n,inf);
  40. start[v]+=rem-1;
  41. len[v]-=rem-1;
  42. link[last]=v=u;
  43. last=u;
  44. }
  45. if(now==1)--rem;
  46. else now=link[now];
  47. }
  48. }
  49. void clear(){
  50. memset(start,0,sizeof(start));
  51. memset(len,0,sizeof(len));
  52. memset(ch,0,sizeof(ch));
  53. memset(link,0,sizeof(link));
  54. memset(s,0,sizeof(s));
  55. tail=now=1;rem=n=0;len[0]=inf;
  56. }
  57. } T;
  58. void predfs(int u,int dep) {
  59. if(dep>=inf) {
  60. int L=T.start[u];
  61. int R=L+T.len[u]-1;
  62. R=min(R,T.n);
  63. for(int i=1; i<=num; ++i) {
  64. if(sum[i][R]-sum[i][L-1]) {
  65. val[u]|=(1<<i);
  66. break;
  67. }
  68. }
  69. return;
  70. }
  71. for(int i=0; i<=25+num; ++i) {
  72. if(T.ch[u][i]) {
  73. predfs(T.ch[u][i],dep+T.len[T.ch[u][i]]);
  74. val[u]|=val[T.ch[u][i]];
  75. }
  76. }
  77. if(val[u]==M)ans=max(ans,dep);
  78. }
  79. inline void print(char* x){
  80. for(int i=1;i<=strlen(x+1);++i)cout<<x[i];
  81. cout<<endl;
  82. }
  83. int main() {
  84. scanf("%d",&Case);
  85. //cout<<M<<endl;
  86. while(Case--) {
  87. scanf("%d",&num);ans=0;M=0;
  88. for(int i=1;i<=num;++i)scanf("%s",Z[i]+1);
  89. int G='0';
  90. int len=strlen(Z[1]+1);
  91. Z[1][++len]=(char)G;
  92. for(int i=2; i<=num; ++i) {
  93. G++;
  94. int L=strlen(Z[i]+1);
  95. for(int j=1; j<=L; ++j)Z[1][++len]=Z[i][j];
  96. Z[1][++len]=(char)G;
  97. }
  98. for(int i=1; i<=num; ++i)M+=(1<<i);
  99. for(int i=1; i<=len; ++i) {
  100. if(Z[1][i]>='a')T.Extend(Z[1][i]-'a');
  101. else T.Extend(Z[1][i]-'0'+1+25);
  102. }
  103. for(int i=1; i<=len; ++i) {
  104. for(int j=1; j<=num; ++j)sum[j][i]=sum[j][i-1];
  105. if(T.s[i]>25) {
  106. int V=T.s[i]-25;
  107. sum[V][i]++;
  108. }
  109. }
  110. predfs(1,0);
  111. cout<<ans<<endl;
  112. T.clear();
  113. memset(val,0,sizeof(val));
  114. memset(sum,0,sizeof(sum));
  115. //print(Z[1]);
  116. }
  117. return 0;
  118. }

【题解】SP10570 【LONGCS - Longest Common Substring】的更多相关文章

  1. SPOJ 10570 LONGCS - Longest Common Substring

    思路 和SPOJ 1812 LCS2 - Longest Common Substring II一个思路,改成多组数据就有三倍经验了 代码 #include <cstdio> #inclu ...

  2. 题解 SP1812 【LCS2 - Longest Common Substring II 】

    对于本题这样的多字符串的子串匹配问题,其实用广义后缀自动机就可以很好的解决,感觉会比普通的后缀自动机做法方便一些. 首先记录出每个节点被多少个字符串更新,也就是记录每个节点有多少个字符串能到达它,可以 ...

  3. LintCode Longest Common Substring

    原题链接在这里:http://www.lintcode.com/en/problem/longest-common-substring/# 题目: Given two strings, find th ...

  4. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

  5. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

  6. 【SP1812】LCS2 - Longest Common Substring II

    [SP1812]LCS2 - Longest Common Substring II 题面 洛谷 题解 你首先得会做这题. 然后就其实就很简单了, 你在每一个状态\(i\)打一个标记\(f[i]\)表 ...

  7. 【SP1811】LCS - Longest Common Substring

    [SP1811]LCS - Longest Common Substring 题面 洛谷 题解 建好后缀自动机后从初始状态沿着现在的边匹配, 如果失配则跳它的后缀链接,因为你跳后缀链接到达的\(End ...

  8. LCS2 - Longest Common Substring II(spoj1812)(sam(后缀自动机)+多串LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

  9. LCS - Longest Common Substring(spoj1811) (sam(后缀自动机)+LCS)

    A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...

随机推荐

  1. CA定义以及功能说明

    当您访问以HTTPS开头的网站时,即表示正在使用CA.CA是Internet的重要组成部分.如果不存在CA,那么将无法安全在线购物以及使用网银在线业务等.什么是CA?CA具体是做什么的,又是如何确保您 ...

  2. oracle 11g 导入表时 提示 ***值太大错误

    导入数据库时,总是提示**值太大,实际值是**的错误. 具体忘了错误代码是什么了 ——! 经查询,这个是由于字符集设置的不是gbk的,导致导入时遇到中文字符出现的问题, 解决方法: 如果可以的话就把数 ...

  3. 小程序里的request

    test.js 代码如下: makeRequest: function (e) { var self = this wx.request({ url: 'http://lt.com/home/inde ...

  4. Java生成1,2,2,3,3,3,4,4,4,4,5...序列

    程序很简单,无须赘述. 竖向输出方式: public class Test { public static void main(String[] args) { int n=0; for(n=1;n& ...

  5. React和Vue的异同

    Vue和React是时下比较受欢迎的三巨头之二,对Angular不慎了解,就不在赘述. React是由Facebook开发的一个js ui框架,其最大的变化就是VirtualDOM和新语法JSX vu ...

  6. ThinkPHP6.0 模型搜索器的使用

    搜索器用于封装查询条件表达式,必须在模型中定义,只有使用模型操作数据时才能用搜索器.调用搜索器时使用的是数据表字段,可以不用定义搜索器方法,默认是 = 条件:如果不是数据表字段,必须定义对应的搜索器方 ...

  7. Django总结(Django十一)

    总结一下自己在完成毕设时写的Django博客: Django的初步启动 pycharm+Django启动我的第一个页面 Django+bootstrap启动登录模板页面 Django中 < a ...

  8. matplotlib | Python强大的作图工具,让你从此驾驭图表(二)

    今天是数据处理专题的第10篇文章,我们继续来聊聊matplot这个工具库. 在上周的文章当中我们介绍了matplot的基本用法,以及展示了一些简单的例子,让大家直观地了解这个工具包.我们可以简单地将它 ...

  9. 关于java基础知识的面试题(一)

    1) Java中能否使用goto? 在C/C++中,goto常被用于跳出多重循环.但goto 语句的使用往往会使程序的可读性降低,所以 Java 不允许 goto 跳转.实际上,自从“goto有害论” ...

  10. apisix网关-构建docker镜像构建及插件化开发

    高能劝退:lua开发,适合小白看!!! 前段时间有个项目,用的java程序做网关,压测tps只有1k多点,惨不忍睹. 后来公司有个大佬改用apisix做网关,tps飙升到1w多. 于是对神奇的apis ...