Description

Input

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

Output

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

Sample Input

1 2
10110
000001110
1011001100

Sample Output

4

解题思路:

L0值具有单调性。

L0值为0时,一定有匹配,为1时只需要考虑字符集,为2时要考虑前后顺序,所以具有单调性,L0越小匹配长度越大,那么可以二分。

这道题要求不能覆盖,所以不能使用简单的Dp来解决,但也很明显,得知一个字符串某一位为结尾时最长匹配长度是很有用的QAQ

所以设f[i]为以文本串i结尾,最长可识别子串的长度,那么startpos就是i-f[i],设Dp[i]表示匹配到i最长(可以不连续,但不小于L0)的最大匹配长度。

为了实现可不连续,Dp[i]初值为Dp[i-1],所以Dp[i]的转移方程就是Dp[i]=max(Dp[i-1],max({Dp[j]+i-j|i-j>=L0}))

转移是O(n2)的过不了,可以将Dp[j]-j与i分离将Dp[j]-j用单调队列维护,就是O(n)的了^_^

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
struct sant{
int tranc[];
int len;
int pre;
}s[];
int siz;
int fin;
int n,m;
char tmp[];
int maxl[];
int dp[];
int x[];
void Insert(int c)
{
int nwp,nwq,lsp,lsq;
nwp=++siz;
s[nwp].len=s[fin].len+;
for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
s[lsp].tranc[c]=nwp;
if(!lsp)
s[nwp].pre=;
else{
lsq=s[lsp].tranc[c];
if(s[lsq].len==s[lsp].len+)
s[nwp].pre=lsq;
else{
nwq=++siz;
s[nwq]=s[lsq];
s[nwq].len=s[lsp].len+;
s[nwp].pre=s[lsq].pre=nwq;
while(s[lsp].tranc[c]==lsq)
{
s[lsp].tranc[c]=nwq;
lsp=s[lsp].pre;
}
}
}
fin=nwp;
return ;
}
bool can(int L0,int len)
{
dp[]=;
int t=,h=;
for(int i=;i<=len;i++)
{
dp[i]=dp[i-];
if(i<L0)
continue;
while(t>=h&&dp[x[t]]-x[t]<=dp[i-L0]-i+L0)t--;
x[++t]=i-L0;
while(t>=h&&x[h]<i-maxl[i])h++;
if(t>=h)
dp[i]=std::max(dp[x[h]]+i-x[h],dp[i]);
}
return *dp[len]>=*len;
}
int main()
{
fin=++siz;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%s",tmp+);
int len=strlen(tmp+);
fin=;
for(int j=;j<=len;j++)
Insert(tmp[j]-'');
}
while(n--)
{
scanf("%s",tmp+);
int len=strlen(tmp+);
int root=;
int mxl=;
for(int i=;i<=len;i++)
{
int c=tmp[i]-'';
if(s[root].tranc[c])
{
root=s[root].tranc[c];
mxl++;
}else{
while(!s[root].tranc[c])
root=s[root].pre;
if(!root)
{
root=;
mxl=;
}else{
mxl=s[root].len+;
root=s[root].tranc[c];
}
}
maxl[i]=mxl;
}
int ans=;
int l=,r=len;
while(l<=r)
{
int mid=(l+r)>>;
if(can(mid,len))
{
ans=mid;
l=mid+;
}else
r=mid-;
}
printf("%d\n",ans);
}
return ;
}

BZOJ2806: [Ctsc2012]Cheat(广义后缀自动机,单调队列优化Dp)的更多相关文章

  1. BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]

    2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...

  2. bzoj 2806 [Ctsc2012]Cheat——广义后缀自动机+单调队列优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2806 只想着怎么用后缀数据结构做,其实应该考虑结合其他算法. 可以二分那个长度 L .设当前 ...

  3. 【BZOJ2806】【CTSC2012】Cheat - 广义后缀自动机+单调队列优化DP

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

  4. 【BZOJ2806】Cheat 【广义后缀自动机+单调队列优化dp+二分】

    题意 有M篇标准作文组成了一个作文库(每篇作文都是一个01的字符串),然后给出N篇作文(自然也是01字符串).如果一个长度不小于L的串在作文库中出现过,那么它是熟悉的.对于某一篇作文,我们要把它分为若 ...

  5. BZOJ 2806 [Ctsc2012]Cheat ——后缀自动机 单调队列优化DP

    先建出广义后缀自动机. 然后跑出文章中每一个位置的最大匹配距离. 然后定义$f[i]$表示匹配到以$i$结尾的串时,最长的匹配距离. 显然可以二分$L$的取值. 然后容易得到$DP$方程 $f[i]= ...

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

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

  7. BZOJ2806 [Ctsc2012]Cheat 【后缀自动机 + 二分 + 单调队列优化DP】

    题目 输入格式 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库 的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 输出格式 N行,每行一个整数,表示这篇作文的 ...

  8. 【BZOJ2806】[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化DP

    [BZOJ2806][Ctsc2012]Cheat Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数接下来M行的01串,表示标准作文库接下来N行的 ...

  9. BZOJ.2806.[CTSC2012]Cheat(广义后缀自动机 DP 单调队列)

    题目链接 首先二分答案L.然后就是判断能否将原串划分出一些长度不小于L的子串,这些子串要是给定n个串中的某个串的子串,且满足它们的长度之和不小于原串长度的90%. 贪心多长选一段什么的显然不对.老老实 ...

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

    [BZOJ2806]Cheat(后缀自动机,二分答案,动态规划,单调队列) 题面 BZOJ 洛谷 题解 很有趣的一道题啊 对于在所有的串上面进行匹配? 很明显的后缀自动机 所以先构建出广义后缀自动机 ...

随机推荐

  1. SQL调用Webservices

    IF NOT object_id('proc_CallWebServices') IS NULL DROP PROCEDURE proc_CallWebServices GO CREATE PROCE ...

  2. HDU 5883 欧拉回路

    题面: 思路: 这里面有坑啊啊啊-.. 先普及一下姿势: 判断无向图欧拉路的方法: 图连通,只有两个顶点是奇数度,其余都是偶数度的. 判断无向图欧拉回路的方法: 图连通,所有顶点都是偶数度. 重点:图 ...

  3. 开源计算机集群监控Ganglia应用视频

    Ganglia源于Berkeley发起的一个开源集群监视项目,设计用于监测数上千节点的计算机集群.它包含gmond.gmetad以及一个Web前端.可以用来监控系统处理器 .内存.硬盘 I/O.网络流 ...

  4. 网络地图WebMap介绍

    WebMap是从ArcGIS Online或者ArcGIS for Portal item上获取显示到用户的界面中. 需要的是地图的ID. 创建一个新的网络地图需要设置ID号,然后再用地图底图MapV ...

  5. Scrapy框架使用代理

    使用代理抓取https://www.baidu.com/s?wd=ip # -*- coding: utf-8 -*- ''' 一.在settings.py中开启中间件 DOWNLOADER_MIDD ...

  6. 解决树莓派新版系统 ssh连接不了问题

    一.解决办法 由于有连接了显示器,所以可以直接输入命令行开启树莓派的SSH,并且使用putty连接就可以. sudo service ssh start sudo service ssh sttus ...

  7. Android学习总结(1)——好的 Android 开发习惯

    Android编码规范 java代码中不出现中文,最多注释中可以出现中文: 局部变量命名.静态成员变量命名:只能包含字母,单词首字母出第一个都为大写,其他字母都为小写: 常量命名:只能包含字母和 ,字 ...

  8. Tomcat线程池与NIO配置

    每个web客户端请求对于服务器端来说就一个单独的线程,客户端的请求数量增多将会导致线程数就上去了,CPU就忙着跟线程切换. 而NIO则是使用单线程(单个CPU)或者只使用少量的多线程(多CPU)来接受 ...

  9. php将数组或字符串写入文件

    //将数组保存在文件里 function export_to_file($file, $variable) { $fopen = fopen($file, 'wb'); if (!$fopen) { ...

  10. 线段树 hdu3642 Get The Treasury

    不得不说,这是一题很经典的体积并.. 然而还是debug了2个多小时... 首先思路:按z的大小排序. 然后相当于扫描面一样,,从体积的最下方向上方扫描,遇到这个面 就将相应的两条线增加到set中,或 ...