在虐各种最长公共子串、子序列的题虐的不耐烦了之后,你决定反其道而行之——被它们虐。

操作一:对A,B分别建SAM,暴力BFS。

操作二:对B建序列自动机或SAM,A在上面暴力匹配。

操作三:对A,B建序列自动机,暴力匹配。

操作四:对B建序列自动机,在自动机上DP。

上面的我一句也看不懂,对不起我重说一遍。

操作一:对B的所有后缀建Trie,A在上面暴力跑。$O(n^2)$

操作二:枚举A的子串,在B上暴力匹配。$O(n^2)$

操作三:在B的每个点上挂一个原本没有的叶子,将从根到这个叶子的路径形成的串扔到A上暴力跑匹配,若A有这个串则更新答案(因为是新叶子故B肯定没有这个串)。但这样似乎是$O(n^3*26)$的,注意枚举点的顺序,按建立顺序从后往前枚举,对于所有深度>=当前ans的直接跳过,这样就近似为$O(n^2*26)$了。似乎可以卡掉,但感觉并不会有出题人去卡。

操作四:DP,f[i][j]表示A的前i个字符中选j个,在B的最小匹配末尾下标的最大值。每次只要从f[pre[i][c]][j-1]转移,其中pre[i][c]为A的第i个位置前的最接近i的字母c的位置。$O(n^2*26)$

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #define rep(i,l,r) for (int i=(l); i<=(r); i++)
  5. using namespace std;
  6.  
  7. const int N=,M=,inf=1e9;
  8. int n,m,nd=,ans,son[M][],fa[M],dep[M],pre[N][],nxt[N][],f[N][N];
  9. char st[M],A[N],B[N],s[N];
  10.  
  11. void ins(int d){
  12. int x=;
  13. rep(i,d,m){
  14. int c=B[i]-'a'+;
  15. if (!son[x][c]) son[x][c]=++nd,fa[nd]=x,st[nd]=B[i],dep[nd]=dep[x]+;
  16. x=son[x][c];
  17. }
  18. }
  19.  
  20. void walk(int d){
  21. int x=;
  22. rep(i,d,n){
  23. int c=A[i]-'a'+;
  24. if (!son[x][c]) { ans=min(ans,i-d+); return; }
  25. x=son[x][c];
  26. }
  27. }
  28.  
  29. void work(int d){
  30. int p=d;
  31. for (int i=; i<=m && p<=n; i++)
  32. if (B[i]==A[p]) p++;
  33. if (p<=n) ans=min(ans,p-d+);
  34. }
  35.  
  36. void work2(int tot){
  37. int p=;
  38. for (int i=; i<=n && p<=tot; i++)
  39. if (A[i]==s[p]) p++;
  40. if (p>tot) ans=min(ans,tot);
  41. }
  42.  
  43. void solve1(){
  44. ans=inf;
  45. rep(i,,n) walk(i);
  46. printf("%d\n",ans==inf ? - : ans);
  47. }
  48.  
  49. void solve2(){
  50. ans=inf;
  51. rep(i,,n) work(i);
  52. printf("%d\n",ans==inf ? - : ans);
  53. }
  54.  
  55. void solve3(){
  56. ans=inf;
  57. for (int i=nd; i; i--) if (dep[i]<ans){
  58. int tot=;
  59. for (int k=i; k>; k=fa[k]) s[++tot]=st[k];
  60. reverse(s+,s+tot+); tot++;
  61. rep(j,,) if (!son[i][j]) s[tot]=j+'a'-,work2(tot);
  62. }
  63. printf("%d\n",ans==inf ? - : ans);
  64. }
  65.  
  66. void solve4(){
  67. ans=inf;
  68. rep(i,,n){
  69. rep(j,,) pre[i][j]=pre[i-][j];
  70. pre[i][A[i-]-'a'+]=i-;
  71. }
  72. for (int i=n-; ~i; i--){
  73. rep(j,,) nxt[i][j]=nxt[i+][j];
  74. nxt[i][B[i+]-'a'+]=i+;
  75. }
  76. rep(i,,n){
  77. int t=nxt[][A[i]-'a'+];
  78. if (t) f[i][]=max(f[i][],t); else { puts(""); return; }
  79. }
  80. rep(i,,n) rep(j,,i) rep(k,,) if (pre[i][k]){
  81. int t=nxt[f[pre[i][k]][j-]][A[i]-'a'+];
  82. if (!t) { ans=min(ans,j); break; }
  83. f[i][j]=max(f[i][j],t);
  84. }
  85. printf("%d\n",ans==inf ? - : ans);
  86. }
  87.  
  88. int main(){
  89. freopen("bzoj4032.in","r",stdin);
  90. freopen("bzoj4032.out","w",stdout);
  91. scanf("%s%s",A+,B+); n=strlen(A+); m=strlen(B+);
  92. rep(i,,m) ins(i);
  93. solve1(); solve2(); solve3(); solve4();
  94. return ;
  95. }

[BZOJ4032][HEOI2015]最短不公共子串(Trie+DP)的更多相关文章

  1. bzoj4032: [HEOI2015]最短不公共子串(SAM+DP)

    4032: [HEOI2015]最短不公共子串 题目:传送门 题解: 陈年老题良心%你赛膜爆嘎爷 当初做题...一眼SAM...结果只会两种直接DP的情况... 情况1: 直接设f[i][j] 表示的 ...

  2. BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心

    题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...

  3. BZOJ4032: [HEOI2015]最短不公共子串(后缀自动机+序列自动机)

    题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...

  4. BZOJ4032:[HEOI2015]最短不公共子串(SAM)

    Description 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列” ...

  5. BZOJ4032 [HEOI2015]最短不公共子串 【后缀自动机 + 序列自动机 + dp】

    题目链接 BZOJ4032 题解 首先膜\(hb\) 空手切神题 一问\(hash\),二问枚举 三问\(trie\)树,四问\(dp\) 南二巨佬神\(hb\) 空手吊打自动机 \(orz orz ...

  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. BZOJ4032 : [HEOI2015]最短不公共子串

    第一问: 对B串建立SAM,暴力枚举A的每个子串,在SAM上走,若失配则可行. 第二问: 设g[i][j]表示B串的第i个字符之后最早出现的字符j的位置,暴力枚举A的每个子串,按照g贪心地走,若失配则 ...

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

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

  9. 【BZOJ4032】[HEOI2015]最短不公共子串(后缀自动机,序列自动机)

    [BZOJ4032][HEOI2015]最短不公共子串(后缀自动机,序列自动机) 题面 BZOJ 洛谷 题解 数据范围很小,直接暴力构建后缀自动机和序列自动机,然后直接在两个自动机上进行\(bfs\) ...

随机推荐

  1. Django之ModelForm(一)

    要说ModelForm,那就先说Form吧! 先给出一个Form示例: models.py from django.db import models class UserType(models.Mod ...

  2. ProxySQL(MGR)部署故障:'sys.gr_member_routing_candidate_status' doesn't exist

    ProxySQL(MGR) 故障排查: 故障现象:runtime_mysql_servers节点状态offline_hostgroup(本案例为15) 日志关键信息: [WARNING] Group ...

  3. MySQL sleep过多解决方法

    睡眠连接过多,会对mysql服务器造成什么影响? 严重消耗mysql服务器资源(主要是cpu, 内存),并可能导致mysql崩溃. 造成睡眠连接过多的原因? 1. 使用了太多持久连接(个人觉得,在高并 ...

  4. HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...

  5. ECMAScript 6 Promise 对象

    一.Promise的含义 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise是一个对象,从它可以获取异步操作的消息. 1. ...

  6. nginx同域名动静态分离

    公司需求是如果是app加载静态页面的话要通过应用服务直接请求指定的服务  由于机房迁移  不得不将该文件迁移到一个指定的地方  需要通过nginx配置检测到是访问该静态页面的就转到该静态页面上面进行加 ...

  7. tftp 开发板ping不通PC机

    开发板:JZ2440(天下2440开发板是一家) 当进入uboot界面时:输入命令print则显示: 将PC端的IP设置为192.168.1.11 在开发板上ping   192.168.1.11,若 ...

  8. 设计模式(一)工厂模式Factory(创建型)(转)

    原文链接:http://blog.csdn.net/hguisu/article/details/7505909 设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符 ...

  9. java并发编程实战笔记---(第五章)基础构建模块

    . 5.1同步容器类 1.同步容器类的问题 复合操作,加容器内置锁 2.迭代器与concurrentModificationException 迭代容器用iterator, 迭代过程中,如果有其他线程 ...

  10. [ JS 进阶 ] Repaint 、Reflow 的基本认识和优化

    你是不是经常听师兄或一些前端前辈说不能用CSS通配符 *,CSS选择器层叠不能超过三层,CSS尽量使用类选择器,书写HTML少使用table,结构要尽量简单-DOM树要小....等这些忠告,以前我就大 ...