题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4032

不是 b 的子串的话就对 b 建后缀自动机,在 a 上枚举从每个位置开始的子串或者找子序列(子序列就是记录 a 的前 i 个,走到 b 的 j 状态用的最短长度),对应到自动机上看看能不能走下去就行了。

不是 b 的子序列的话就对 b 建子序列自动机?就是那个知道每个位置再填一个字符会走到哪个位置的数组。然后在 a 上枚举,看看自动机上能不能走下去就行了。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int N=,M=,K=;
  6. char a[N],b[N];
  7. int n,m,cnt=,lst=,go[M][K],fa[M],l[M],nxt[N][K],lt[K];
  8. int dp[N][M];//M//int
  9. int Mn(int a,int b){return a<b?a:b;}
  10. void add(int w)
  11. {
  12. int p=lst,np=++cnt;lst=np;l[np]=l[p]+;
  13. for(;p&&!go[p][w];p=fa[p])go[p][w]=np;
  14. if(!p)fa[np]=;
  15. else
  16. {
  17. int q=go[p][w];
  18. if(l[q]==l[p]+)fa[np]=q;
  19. else
  20. {
  21. int nq=++cnt;l[nq]=l[p]+;
  22. fa[nq]=fa[q];fa[q]=nq;fa[np]=nq;
  23. memcpy(go[nq],go[q],sizeof go[q]);
  24. for(;go[p][w]==q;p=fa[p])go[p][w]=nq;
  25. }
  26. }
  27. }
  28. void solve1()
  29. {
  30. int ans=n+;
  31. for(int i=;i<=n;i++)
  32. {
  33. int cr=;
  34. for(int j=i;j<=n;j++)
  35. {
  36. if(!go[cr][a[j]-'a'+])
  37. {ans=Mn(ans,j-i+);break;}
  38. cr=go[cr][a[j]-'a'+];
  39. }
  40. }
  41. printf("%d\n",ans>n?-:ans);
  42. }
  43. void solve2()
  44. {
  45. int ans=n+;
  46. for(int t=;t<=n;t++)
  47. {
  48. int cr=;
  49. for(int i=t;i<=n;i++)
  50. {
  51. int d=a[i]-'a'+;
  52. if(nxt[cr][d])cr=nxt[cr][d];
  53. else {ans=Mn(ans,i-t+);break;}
  54. }
  55. }
  56. printf("%d\n",ans>n?-:ans);
  57. }
  58. void solve3()
  59. {
  60. memset(dp,0x3f,sizeof dp);
  61. dp[][]=; int ans=n+;
  62. for(int i=;i<=n;i++)
  63. {
  64. int d=a[i]-'a'+;
  65. for(int j=;j<=cnt;j++)
  66. if(dp[i-][j]<=n)
  67. {
  68. dp[i][j]=Mn(dp[i][j],dp[i-][j]);
  69. if(!go[j][d])ans=Mn(ans,dp[i-][j]+);
  70. else dp[i][go[j][d]]=Mn(dp[i][go[j][d]],dp[i-][j]+);
  71. }
  72. }
  73. printf("%d\n",ans>n?-:ans);
  74. }
  75. void solve4()
  76. {
  77. memset(dp,0x3f,sizeof dp);
  78. dp[][]=; int ans=n+;
  79. for(int i=;i<=n;i++)
  80. {
  81. int d=a[i]-'a'+;
  82. for(int j=;j<=m;j++)
  83. if(dp[i-][j]<=n)
  84. {
  85. dp[i][j]=Mn(dp[i][j],dp[i-][j]);
  86. if(!nxt[j][d])ans=Mn(ans,dp[i-][j]+);
  87. else dp[i][nxt[j][d]]=Mn(dp[i][nxt[j][d]],dp[i-][j]+);
  88. }
  89. }
  90. printf("%d\n",ans>n?-:ans);
  91. }
  92. int main()
  93. {
  94. scanf("%s",a+);scanf("%s",b+);
  95. n=strlen(a+);m=strlen(b+);
  96. for(int i=;i<=m;i++)add(b[i]-'a'+);
  97. for(int i=m;i>=;i--)
  98. {
  99. for(int j=;j<=;j++)
  100. nxt[i][j]=lt[j];
  101. lt[b[i]-'a'+]=i;
  102. }
  103. solve1();solve2();
  104. solve3();solve4();
  105. return ;
  106. }

bzoj 4032 [HEOI2015]最短不公共子串——后缀自动机的更多相关文章

  1. BZOJ 4032: [HEOI2015]最短不公共子串 后缀自动机 暴力

    4032: [HEOI2015]最短不公共子串 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4032 Description 在虐各种最 ...

  2. BZOJ 4032: [HEOI2015]最短不公共子串(后缀自动机+记忆化搜索)

    传送门 解题思路 首先需要预处理两个串\(nxt(i)(j)\)表示i位置之后最近的\(j\). 第一问直接对\(b\)建后缀自动机,枚举\(a\)的起点暴力匹配. 第二问枚举\(a\)的起点,\(b ...

  3. bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp)

    bzoj4032/luoguP4112 [HEOI2015]最短不公共子串(后缀自动机+序列自动机上dp) bzoj Luogu 题解时间 给两个小写字母串 $ A $ , $ B $ ,请你计算: ...

  4. BZOJ 4032: [HEOI2015]最短不公共子串

    4032: [HEOI2015]最短不公共子串 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 446  Solved: 224[Submit][Sta ...

  5. BZOJ.4032.[HEOI2015]最短不公共子串(DP 后缀自动机)

    题目链接 1.求A的最短子串,它不是B的子串. 子串是连续的,对B建SAM,枚举起点,在SAM上找到第一个无法匹配点即可.O(n)用SAM能做吗..开始想错了. 2.求A的最短子串,它不是B的子序列. ...

  6. bzoj 4032: [HEOI2015]最短不公共子串【dp+SAM】

    第一.二问: 就是最小的最长公共长度+1,设f[i][j]为a匹配到i,b匹配到j,第一问的转移是f[i][j]=(a[i]==b[j]?f[i-1][j-1]+1:0),第二问的转移是f[i][j] ...

  7. BZOJ 4032: [HEOI2015]最短不公共子串 (dp*3 + SAM)

    转博客大法好 第4个子任务中,为什么只转移最近的一个位置,自己YY吧(多YY有益身体健康). #include <bits/stdc++.h> using namespace std; t ...

  8. bzoj 4032 [ HEOI 2015 ] 最短不公共子串 —— 后缀自动机+序列自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4032 序列自动机其实就是每个位置记录一下某字母后面第一个出现位置,为了子序列能尽量长. 对字 ...

  9. 【BZOJ】4032: [HEOI2015]最短不公共子串(LibreOJ #2123)

    [题意]给两个小写字母串A,B,请你计算: (1) A的一个最短的子串,它不是B的子串 (2) A的一个最短的子串,它不是B的子序列 (3) A的一个最短的子序列,它不是B的子串 (4) A的一个最短 ...

随机推荐

  1. Ubuntu系统Anaconda下载安装与切换源教程【转】

    本文转载自:https://blog.csdn.net/qq_36268036/article/details/81517893 1. 下载安装: 这里选用国内清华大学的Tuna开源软件镜像站作为演示 ...

  2. 【P2944】地震损失(最大流,洛谷)

    绝对难度虚高的一题 看到题目,至少损坏几个房子,开始考虑最小割,建的是双向边,所以拆点,边权除了自己与自己的之外都连inf.然后把所有求救的点都连到超级源上,跑一遍最大流就可以了. #include& ...

  3. 监控系统信息模块psutil

    About psutil (python system and process utilities) is a cross-platform library for retrieving inform ...

  4. NumPy矩阵库

    NumPy - 矩阵库 NumPy 包包含一个 Matrix库numpy.matlib.此模块的函数返回矩阵而不是返回ndarray对象. matlib.empty() matlib.empty()函 ...

  5. scala学习手记27 - 下划线与参数

    在Scala里,下划线(_)可以表示函数值的参数.如果某个参数在函数里仅使用一次,就可以用下划线表示.每次在函数里用下划线,都表示随后的参数. val arr = Array(1, 2, 3, 4, ...

  6. 带你彻底明白 Android Studio 打包混淆

    前言 在使用Android Studio混淆打包时,该IDE自身集成了Java语言的ProGuard作为压缩,优化和混淆工具,配合Gradle构建工具使用很简单.只需要在工程应用目录的gradle文件 ...

  7. Http请求原理与相关知识

    1.在浏览器地址栏输入URL,按回车后经过了哪些步骤  1-1. 浏览器向DNS服务器请求解析该URL中的域名及所对应的IP地址; 1-2. 解析出IP地址后,根据该IP地址和默认端口80与服务器建立 ...

  8. spring mvc:常用标签库(文本框,密码框,文本域,复选框,单选按钮,下拉框隐藏于,上传文件等)

    在jsp页面需要引入:<%@taglib uri="http://www.springframework.org/tags/form" prefix="form&q ...

  9. 卸载MicrosoftBAF(删除C:\CommonFramework\instdata.dat)

    发现有个可疑文件夹 C:\CommonFramework ,而且还会不停的删除创建 C:\CommonFramework\instdata.dat 最后被发现这是必应的一个框架程序在捣鬼,在微软论坛里 ...

  10. hdu 5980 Find Small A(水,模拟)

    Find Small A Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...