题目描述

输入

第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数
接下来M行的01串,表示标准作文库
接下来N行的01串,表示N篇作文

输出

N行,每行一个整数,表示这篇作文的Lo 值。

样例输入

1 2
10110
000001110
1011001100

样例输出

4


题解

广义后缀自动机+二分+单调队列优化dp

先建立广义后缀自动机,然后处理出“每篇作文”中的每个字符最多可以向前匹配多少个字符。

这个方法在 陈老师的ppt 中讲过。

对于一个字符,若当前位置存在对应的next指针,则最大匹配长度++,并将当前位置移至对于指针。否则不断在parent树上查找,直到存在next指针,那么最大匹配长度为此位置的dis值+1,并将当前位置赋为此位置的next指针;如果找不到next指针,则最大匹配长度为0,将当前位置赋为root。

处理出最大匹配长度后,考虑怎样求答案。

显然答案是可以二分的,所以我们二分答案,然后求出该L值=mid下的最大“熟悉”长度。

设f[i]表示前i个字符的最大“熟悉”长度,mx[i]为第i个字符的最大匹配长度,那么有状态转移方程$f[i]=f[i-1]\ ,\ f[i]=f[j]+i-j\ (i-mx[i]\le j\le i-mid)$。

那么我们用单调队列维护f[j]-j的最大值即可再$O(n)$时间内求出f[n],最后判断f[n]/n是否≥0.9即可。这里有精度问题,所以需要把除法转化为乘法来求。

根据二分结果调整边界即可得到答案。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1100010
using namespace std;
int next[N << 1][2] , fa[N << 1] , dis[N << 1] , last , tot = 1 , n , mx[N] , f[N] , q[N];
char str[N];
void ins(int c)
{int p = last , np = last = ++tot;dis[np] = dis[p] + 1;while(p && !next[p][c]) next[p][c] = np , p = fa[p];if(!p) fa[np] = 1;else{int q = next[p][c];if(dis[q] == dis[p] + 1) fa[np] = q;else{int nq = ++tot;memcpy(next[nq] , next[q] , sizeof(next[q])) , dis[nq] = dis[p] + 1 , fa[nq] = fa[q] , fa[np] = fa[q] = nq;while(p && next[p][c] == q) next[p][c] = nq , p = fa[p];}}
}
bool judge(int mid)
{int i , l = 1 , r = 0;for(i = 1 ; i <= n ; i ++ ) f[i] = 0;for(i = mid ; i <= n ; i ++ ){f[i] = f[i - 1];while(l <= r && f[q[r]] - q[r] < f[i - mid] - i + mid) r -- ;q[++r] = i - mid;while(l <= r && q[l] < i - mx[i]) l ++ ;if(l <= r) f[i] = max(f[i] , f[q[l]] - q[l] + i);}return f[n] * 10 >= n * 9;
}
int main()
{int T , m , i , j , len , p , l , r , mid , ans;scanf("%d%d" , &T , &m);for(i = 1 ; i <= m ; i ++ ){scanf("%s" , str + 1) , len = strlen(str + 1) , last = 1;for(j = 1 ; j <= len ; j ++ ) ins(str[j] - '0');}while(T -- ){scanf("%s" , str + 1) , n = strlen(str + 1);for(p = i = 1 , len = 0 ; i <= n ; i ++ ){if(next[p][str[i] - '0']) len ++ , p = next[p][str[i] - '0'];else{while(p && !next[p][str[i] - '0']) p = fa[p];if(p) len = dis[p] + 1 , p = next[p][str[i] - '0'];else len = 0 , p = 1;}mx[i] = len;}l = 1 , r = n , ans = 0;while(l <= r){mid = (l + r) >> 1;if(judge(mid)) ans = mid , l = mid + 1;else r = mid - 1;}printf("%d\n" , ans);}return 0;
}

转载于:https://www.cnblogs.com/GXZlegend/p/7115471.html

【bzoj2806】[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化dp相关推荐

  1. BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...

  2. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

  3. poj 2373(单调队列优化dp)

    在长为L(<=1000000)的草地(可看成线段)上装喷水头,喷射是以这个喷水头为中心,喷水头的喷洒半径是可调节的调节范围为[a,b].要求草地的每个点被且只被一个喷水头覆盖,并且有些连续区间必 ...

  4. poj 1821(单调队列优化dp)

    题意:有一道线性篱笆由N个连续的木板组成.有K个工人,你要叫他们给木板涂色.每个工人有3个参数:L 表示 这个工人可以涂的最大木板数目,S表示这个工人站在哪一块木板,P表示这个工人每涂一个木板可以得到 ...

  5. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  6. 【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)

    题干: 在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 nn 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币.但是这个游戏比较坑,里面竟然有负数,表示你要支付多少蒜币.因为这些数字都是可见的,所 ...

  7. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  8. POJ 1821 Fence(单调队列优化DP)

    题解 以前做过很多单调队列优化DP的题. 这个题有一点不同是对于有的状态可以转移,有的状态不能转移. 然后一堆边界和注意点.导致写起来就很难受. 然后状态也比较难定义. dp[i][j]代表前i个人涂 ...

  9. 【单调队列优化DP】烽火传递 LibreOJ - 10180

    题目来源 点我进入提交题目 反思 因为目前在学习单调队列优化DP,所以会往单调队列上面想.然后犯了一个错误就是,认为这个题目只要用单调队列就可以完成,单调队列只是用来减少时间复杂度的,遇到了求最优解的 ...

  10. AcWing 1089 烽火传递 题解(动态规划—DP—单调队列优化DP)

    AcWing 1089 烽火传递 单调队列优化DP,思路比较简单,维护一个保持元素单调递增的单调队列,队首就是第i座烽火台能接收到的,代价最小的方案,加上第i座烽火台的代价就是这座烽火台的最小值 #i ...

最新文章

  1. Linux安装无法运行install,Linux新手安装Debian-8.2.0可能遇到的问题
  2. 结合MongoDB开发LBS应用
  3. C++八皇后拼图,打印所有的算法(附完整源码)
  4. Python--简单的目录扫描脚本
  5. Min_25筛有关求解次小质因子
  6. nssl1211-好文章【字符串hash,map】
  7. LeetCode 70. 爬楼梯 (递归斐波那契 | 动态规划)
  8. scala从url或者其他数据源读取数据
  9. 强大的 actuator 服务监控与管理
  10. angular框架的SmartAdmin模板 如何请求后台数据
  11. Github上优秀的开源小程序汇总
  12. 我的2018OKR年终回顾与2019OKR初步规划
  13. PostgreSQL数据库日常学习笔记13-约束
  14. 年薪90万的阿里p7和副处级干部选哪个?
  15. torch.nn.functional.normalize详解
  16. 柔性橡胶发泡材料(FEF)保温材料英国UKCA 认证 - EN 14304
  17. shell命令 ffmpeg 批量提取视频的音频文件
  18. R12 Customer新建或更新时的工作过程 - DQM Serial Sync Index Program
  19. 最简单的python使用ddddocr模块在线识别验证码后登录
  20. Danar程序员之家在CSDN安家落户啦

热门文章

  1. 首席架构师眼中的架构应该是怎样的?
  2. JVM的4种垃圾回收算法、垃圾回收机制与总结
  3. shell应用之简单计算器
  4. Python实现批量处理扫描特定目录
  5. serversql数据库的查询操作
  6. String、StringBuffer与StringBuilder的区别
  7. CSS3图片动画展示----心跳
  8. JS1 js获取dom元素方法
  9. OC语言-04-OC语言-核心语法
  10. windows 下 YII2 配置 memcache