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. [Java开发之路](6)File类的使用

    1. 构造方法 构造方法 描写叙述 File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建一个新的文件实例. File(String parent , String ...

  2. SQL函数-str()

    1 str()函数用于将数值类型数据转换未字符类型. 2 str()函数语法 select str(数字类型的表达式[,表达式总长度][,小数点后面的位数]) 表达式总长度和小数点后面的位数为可选择参 ...

  3. lslpp 总结

    lslpp action 字段状态值: APPLY应用文件集 CLEANUP清理文件集进行 COMMIT提交文件集 REJECT拒绝指定文件集     status 字段状态值: 标识安装操作历史记录 ...

  4. 网络爬虫与web之间的访问授权协议——Robots

    网站的管理者们通常会有这样一种心态:一方面期待百度.Google这样的搜索引擎来抓取网站的内容,另一方面又很厌恶其他来路不明的网络爬虫抓取自己的信息.正是因为这样,才有“好爬虫”.“坏爬虫”这样的说法 ...

  5. selenium+python 安装使用

    一.序言 selenium官网selenium简单教程selenium完整教程python基础教程 二.安装python3 https://www.python.org/downloads/relea ...

  6. 【Linux下tar命令详解】

    tar命令用于建立.还原备份文件,它可以加入.解开备份文件内的文件. 参数 带有*号的为常用的参数 . -A 新增压缩文件到已存在的压缩包 . -c 建立新的压缩文件* . -d 记录文件的差别 . ...

  7. Swift学习笔记(12)--数组和字典的复制

    Swift中,数组Array和字典Dictionary是用结构来实现的,但是数组与字典和其它结构在进行赋值或者作为参数传递给函数的时候有一些不同. 并且数组和字典的这些操作,又与Foundation中 ...

  8. CentOs虚拟机能够互相ping通,但无法訪问虚拟机服务

    CentOs虚拟机能够互相ping通,但无法訪问虚拟机服务 虚拟机ip:192.168.0.57 主机 ip:192.168.0.80 在虚拟机上搭建了php环境.虚拟机CentOs,主机win7 虚 ...

  9. I帧、P帧和B帧的特点

    I帧:帧内编码帧 I帧特点: 1.它是一个全帧压缩编码帧.它将全帧图像信息进行JPEG压缩编码及传输; 2.解码时仅用I帧的数据就可重构完整图像; 3.I帧描写叙述了图像背景和运动主体的详情; 4.I ...

  10. 一入python深似海--对象的属性

    Python中一切皆是对象,每一个对象都能够有多个属性.Python是怎样管理这些属性呢?我们来探讨一下. 属性的__dict__系统 对象的属性包括两部分:类属性和对象属性.对象的属性可能来自于其类 ...