【BZOJ2806】Cheat(后缀自动机,二分答案,动态规划,单调队列)

题面

BZOJ

洛谷

题解

很有趣的一道题啊

对于在所有的串上面进行匹配?

很明显的后缀自动机

所以先构建出广义后缀自动机

然后这个拆分很像一个\(dp\)

同时,要求的东西很像一个可以二分的样子

所以二分一个答案,考虑如何\(dp\)

设\(f[i]\)表示处理完前\(i\)个字符,能够匹配上的最多的字符个数

转移是\(f[i]=max(f[j]+i-j)\),满足\(i-j>mid\)

同时\(S[j+1..i]\)能够匹配上

因此,可以提前预处理出每个位置能够匹配上的最大长度

然后利用单调队列进行转移就行啦

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<set>
  8. #include<map>
  9. #include<vector>
  10. #include<queue>
  11. using namespace std;
  12. #define ll long long
  13. #define RG register
  14. #define MAX 1111111
  15. inline int read()
  16. {
  17. RG int x=0,t=1;RG char ch=getchar();
  18. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  19. if(ch=='-')t=-1,ch=getchar();
  20. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  21. return x*t;
  22. }
  23. struct Node
  24. {
  25. int son[2];
  26. int ff,len;
  27. }t[MAX];
  28. char ch[MAX];
  29. int p[MAX],f[MAX];
  30. int last=1,tot=1;
  31. int Q[MAX],H,T;
  32. int n,m;
  33. void extend(int c)
  34. {
  35. int p=last,np=++tot;last=np;
  36. t[np].len=t[p].len+1;
  37. while(p&&!t[p].son[c])t[p].son[c]=np,p=t[p].ff;
  38. if(!p)t[np].ff=1;
  39. else
  40. {
  41. int q=t[p].son[c];
  42. if(t[q].len==t[p].len+1)t[np].ff=q;
  43. else
  44. {
  45. int nq=++tot;
  46. t[nq]=t[q];
  47. t[nq].len=t[p].len+1;
  48. t[q].ff=t[np].ff=nq;
  49. while(p&&t[p].son[c]==q)t[p].son[c]=nq,p=t[p].ff;
  50. }
  51. }
  52. }
  53. void pre()
  54. {
  55. int len=strlen(ch+1);
  56. int now=1,ml=0;
  57. for(int i=1;i<=len;++i)
  58. {
  59. int c=ch[i]-48;
  60. if(t[now].son[c])now=t[now].son[c],ml+=1;
  61. else
  62. {
  63. while(now&&!t[now].son[c])now=t[now].ff;
  64. if(!now)ml=0,now=1;
  65. else ml=t[now].len+1,now=t[now].son[c];
  66. }
  67. p[i]=ml;
  68. }
  69. }
  70. bool check(int k)
  71. {
  72. int l=strlen(ch+1);
  73. H=1;T=0;
  74. for(int i=1;i<=l;++i)
  75. {
  76. f[i]=f[i-1];
  77. if(i<k)continue;
  78. while(H<=T&&f[Q[T]]-Q[T]<=f[i-k]-i+k)--T;
  79. Q[++T]=i-k;
  80. while(H<=T&&Q[H]<i-p[i])++H;
  81. if(H<=T)f[i]=max(f[i],f[Q[H]]+i-Q[H]);
  82. }
  83. return f[l]*10>=l*9;
  84. }
  85. int main()
  86. {
  87. n=read();m=read();
  88. while(m--)
  89. {
  90. last=1;
  91. scanf("%s",ch+1);
  92. for(int i=1,l=strlen(ch+1);i<=l;++i)extend(ch[i]-48);
  93. }
  94. while(n--)
  95. {
  96. scanf("%s",ch+1);
  97. int len=strlen(ch+1);
  98. pre();
  99. int l=1,r=len,ans=0;
  100. while(l<=r)
  101. {
  102. int mid=(l+r)>>1;
  103. if(check(mid))ans=mid,l=mid+1;
  104. else r=mid-1;
  105. }
  106. printf("%d\n",ans);
  107. }
  108. return 0;
  109. }

【BZOJ2806】Cheat(后缀自动机,二分答案,动态规划,单调队列)的更多相关文章

  1. Luogu4022 CTSC2012熟悉的文章(广义后缀自动机+二分答案+动态规划+单调队列)

    对作文库中的串建出广义SAM,然后显然可以二分答案,二分之后考虑暴力dp,设f[i]为前i位最长匹配长度,显然有f[i]=max(f[i-1],f[j]+i-j) (i-j>=l&&am ...

  2. [CTSC2012]熟悉的文章(广义后缀自动机+二分答案+单调队列优化DP)

    我们对作文库建出广义后缀自动机.考虑用\(SAM\)处理出来一个数组\(mx[i]\),表示从作文的第\(i\)个位置向左最远在作文库中出现的子串的长度.这个东西可以在\(SAM\)上跑\(trans ...

  3. BZOJ 2806 [Ctsc2012]Cheat (后缀自动机+二分+单调队列+dp)

    题目大意: 给你一堆模式串和文本串 对于每个文本串,我们可以把它不可重叠地拆分成很多子串,如果拆分出的串作为子串出现在了任何一个模式串中,我们称它是“眼熟的”,我们必须保证“眼熟的”子串总长度不小于文 ...

  4. Luogu4022 CTSC2012 熟悉的文章 广义SAM、二分答案、单调队列

    传送门 先将所有模板串扔进广义SAM.发现作文的\(L0\)具有单调性,即\(L0\)更小不会影响答案,所以二分答案. 假设当前二分的值为\(mid\),将当前的作文放到广义SAM上匹配. 设对于第\ ...

  5. 【洛谷 P1419】 寻找段落(二分答案,单调队列)

    题目链接 开始还以为是尺取.发现行不通. 一看标签二分答案,恍然大悟. 二分一个\(mid\)(实数),把数列里每个数减去\(mid\),然后求前缀和,在用单调队列维护\(sum[i-t\text{~ ...

  6. BZOJ_1044_[HAOI2008]木棍分割_二分答案+DP+单调队列

    BZOJ_1044_[HAOI2008]木棍分割_二分答案+DP Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个 ...

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

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

  8. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  9. Poj 3261 Milk Patterns(后缀数组+二分答案)

    Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...

  10. [bzoj2806][Ctsc2012]Cheat(后缀自动机(SAM)+二分答案+单调队列优化dp)

    偷懒直接把bzoj的网页内容ctrlcv过来了 2806: [Ctsc2012]Cheat Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1943   ...

随机推荐

  1. 十、Django之Admin

    一.Django Admin 管理工具 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中 ...

  2. 一次性搞定Session

    相信很多人遇到过同一个浏览器会出现Session覆盖问题.今天主要针对Session覆盖问题来看看Session是如何工作的.那么先看一张简单的图说明一下 上面的图大致的说明Session工作简单创建 ...

  3. 利用工厂模式实现serviec层和dao层解耦

    利用工厂模式实现serveice和dao层的解耦,这样就可以不用在service层实例化dao层的对象,当dao层代码发生改变的时候(数据库实现发生改变)直接修改配置文件就不用改变service层的代 ...

  4. MAC下Android的Eclipse开发环境搭建

    原文链接:https://www.cnblogs.com/macro-cheng/archive/2011/09/30/android-001.html 一.Eclipse的下载 到网站:http:/ ...

  5. openvpn部署

    原文发表于cu:2016-03-29 参考文档: 安装:http://qicheng0211.blog.51cto.com/3958621/1575273 安装:http://www.ipython. ...

  6. We are writing to let you know we have removed your selling privileges

     Hello, We are writing to let you know we have removed your selling privileges, canceled your listin ...

  7. selenium--判断元素是否存在

    # coding:utf-8from selenium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitf ...

  8. A Bug's Life(加权并查集)

    Description Background  Professor Hopper is researching the sexual behavior of a rare species of bug ...

  9. C++:this指针的简单理解

    一.什么是this指针 要想理解什么是this指针,首先必须理解在C++中是如何为类的对象分配内存空间的. #include<iostream> using namespace std; ...

  10. CodeForces 479C Exams 贪心

    题目: C. Exams time limit per test 1 second memory limit per test 256 megabytes input standard input o ...