传送门

解题思路

  肯定先要建出来广义后缀自动机。刚开始以为是个二分+贪心,写了一下结果\(20\)分。说一下正解,首先显然\(L_0\)具有单调性,是可以二分的。考虑二分后怎样判合法,对于分割序列很容易想到\(dp\),设\(f_i\)表示前\(i\)个字符匹配成功数量,那么有转移方程\(f_i=max(f_j+i-j)(i-j>=L\) 且 \(j\)到\(i\)可以匹配 \()\),\(L\)是二分出来的限制,判断是否能匹配可以预处理,预处理出\(mth_i\)表示\(i\)最多能与往前\(mth_i\)位匹配成功,那么第二个条件就变成了\(j>=i-mth_i\)。如果这样做是\(O(n^2logn)\)的,实测可以拿到\(75\)分2333。考虑优化,发现\(i-mth_i\)具有单调性,因为每移动一格\(i\)会\(+1\),而\(mth_i\)最多\(+1\)。那么可以用一个单调递减队列来优化,每次将\(i-lim\)入队,取出队头更新答案,时间复杂度为\(O(nlogn)\)。

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<algorithm>
  6. using namespace std;
  7. const int N=1100005<<1;
  8. int n,m,res,ans,f[N],mth[N],q[N],hd,tl;
  9. char s[N];
  10. struct SAM{
  11. int ch[N][2],fa[N],l[N],lst,cnt;
  12. void Insert(int c){
  13. int p=lst,np=++cnt; l[np]=l[p]+1; lst=cnt;
  14. for(;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
  15. if(!p) fa[np]=1;
  16. else {
  17. int q=ch[p][c];
  18. if(l[p]+1==l[q]) fa[np]=q;
  19. else {
  20. int nq=++cnt; l[nq]=l[p]+1;
  21. memcpy(ch[nq],ch[q],sizeof(ch[nq]));
  22. fa[nq]=fa[q]; fa[q]=fa[np]=nq;
  23. for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
  24. }
  25. }
  26. }
  27. void prework(int len){
  28. int now=1,num=0;
  29. for(int i=1;i<=len;i++){
  30. if(ch[now][s[i]-'0']) now=ch[now][s[i]-'0'],num++;
  31. else {
  32. for(;now && !ch[now][s[i]-'0'];now=fa[now]);
  33. if(!now) now=1,num=0;
  34. else num=l[now]+1,now=ch[now][s[i]-'0'];
  35. }
  36. mth[i]=num;
  37. }
  38. }
  39. bool check(int lim,int len){
  40. int tmp; hd=1; tl=0;
  41. for(int i=1;i<=len;i++){
  42. f[i]=f[i-1]; if(i<lim) continue; tmp=i-mth[i];
  43. while(hd<=tl && f[q[tl]]-q[tl]<=f[i-lim]-i+lim) tl--;
  44. q[++tl]=i-lim;
  45. while(hd<=tl && q[hd]<tmp) hd++;
  46. if(hd<=tl) f[i]=max(f[i],f[q[hd]]-q[hd]+i);
  47. }
  48. // for(int i=1;i<=len;i++){
  49. // f[i]=f[i-1];
  50. // for(int j=max(0,i-mth[i]);j+lim<=i;j++)
  51. // f[i]=max(f[i],f[j]+i-j);
  52. // }
  53. return len-f[len]>res?0:1;
  54. }
  55. void solve(int len){
  56. prework(len);
  57. int L=1,R=len,mid;
  58. while(L<=R){
  59. mid=(L+R)>>1;
  60. if(check(mid,len)) L=mid+1,ans=mid;
  61. else R=mid-1;
  62. }
  63. printf("%d\n",ans);
  64. }
  65. }sam;
  66. int main(){
  67. scanf("%d%d",&n,&m); sam.cnt=1; int len;
  68. for(int i=1;i<=m;i++){
  69. scanf("%s",s+1); sam.lst=1;
  70. len=strlen(s+1);
  71. for(int j=1;j<=len;j++) sam.Insert(s[j]-'0');
  72. }
  73. for(int i=1;i<=n;i++){
  74. scanf("%s",s+1); len=strlen(s+1);
  75. res=(len*9+9)/10; res=len-res;
  76. sam.solve(len); ans=0;
  77. }
  78. return 0;
  79. }

BZOJ 2806: [Ctsc2012]Cheat(单调队列优化dp+后缀自动机)的更多相关文章

  1. bzoj 2216: Lightning Conductor 单调队列优化dp

    题目大意 已知一个长度为\(n\)的序列\(a_1,a_2,...,a_n\)对于每个\(1\leq i\leq n\),找到最小的非负整数\(p\)满足: 对于任意的\(j\), \(a_j \le ...

  2. BZOJ 1233 干草堆 (单调队列优化DP)

    $ BZOJ~1233~~ $ 干草堆: (题目特殊性质) $ solution: $ 很妙的一道题目,开始看了一眼觉得是个傻逼贪心,从后往前当前层能多短就多短,尽量节省花费.但是这是DP专题,怎么会 ...

  3. BZOJ 1855 股票交易(单调队列优化DP)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1855 题意:最近lxhgww又迷上了投资股票, 通过一段时间的观察和学习,他总结出了股票 ...

  4. BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP

    BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...

  5. bzoj 1499 [NOI2005]瑰丽华尔兹——单调队列优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1499 简单的单调队列优化dp.(然而当时却WA得不行.今天总算填了坑) 注意滚动数组赋初值应 ...

  6. 单调队列优化DP || [NOI2005]瑰丽华尔兹 || BZOJ 1499 || Luogu P2254

    题外话:题目极好,做题体验极差 题面:[NOI2005]瑰丽华尔兹 题解: F[t][i][j]表示第t时刻钢琴位于(i,j)时的最大路程F[t][i][j]=max(F[t-1][i][j],F[t ...

  7. P4381 [IOI2008]Island(基环树+单调队列优化dp)

    P4381 [IOI2008]Island 题意:求图中所有基环树的直径和 我们对每棵基环树分别计算答案. 首先我们先bfs找环(dfs易爆栈) 蓝后我们处理直径 直径不在环上,就在环上某点的子树上 ...

  8. 【笔记篇】单调队列优化dp学习笔记&&luogu2569_bzoj1855股票交♂易

    DP颂 DP之神 圣洁美丽 算法光芒照大地 我们怀着 崇高敬意 跪倒在DP神殿里 你的复杂 能让蒟蒻 试图入门却放弃 在你光辉 照耀下面 AC真心不容易 dp大概是最经久不衰 亘古不化的算法了吧. 而 ...

  9. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

随机推荐

  1. input只输入数字和小数后两位

    html:<input  name="" type="tel" value="" placeholder="请输入金额&qu ...

  2. 用SPSS做时间序列

    用SPSS做时间序列 关于时间序列,有好多软件可以支持分析,大家比较熟悉的可能是EVIEWS.SPSS.还有STATA,具体用啥软件,结果都是一样的,但是SPSS作为一款学习简单,使用容易的软件还是值 ...

  3. Entity Framework 中遇到的一些小问题

    一.在多表关联中,一个表中有另一个表的model累,在Include方法里提示lambda表达式不是委托类型,这时候需要using System.Data.Entity; 二.插入数据时,主键并非自增 ...

  4. JavaWeb防止用户的重复请求提交

    这里实现这个重复提交的防止,是通过在一个FIlter过滤器中生成一个令牌token,保存在Session域中,然后在对这个token加密得到ciphertext(密文),将密文保存在request域中 ...

  5. C++中使用CMake编译管理项目

    CMake是一个跨平台的Makefile生成工具,可以根据特定的规则生成相应的Makefile文件,并对C/C++源代码进行编译和管理. 有一篇博客介绍CMake的使用,比较通俗易懂,链接地址是:Cm ...

  6. WPS for linux 中不能切换到中文输入法

    转载自:http://blog.sciencenet.cn/blog-200199-1032795.html 尽管安装有中文输入法,wps有时仍然不能切换到中文输入法,此问题解决方案如下: 根账户下打 ...

  7. TCP协议-流量控制

    流量控制是通过滑动窗口来实现控制的.使用了坚持定时器,防止发送失败导致死锁.

  8. eclipse 从git取项目,导入为maven项目,新加的方法,报加载主类错误

    eclipse 从git取项目,导入为maven项目,新加的方法,报加载主类错误 具体描述: 整体编译能够编译成功,但新加一个java,里面创建一个main方法,运行时,报无法加载主类的错误, 整体编 ...

  9. [NOIP2016]借教室

    NOIP2012提高组D2T2. 这道题目非常基础,正解貌似是二分+差分数组,在这里提供一种线段树的思路. 很容易发现题目让我们每次修改一段区间,然后我们只需要看每一个区间内有没有负数就可以了.可以用 ...

  10. Yii框架怎么寻找对应视图

    render()内容; public function render($view,$data=null,$return=false) { if($this->beforeRender($view ...