先建出广义后缀自动机。

然后跑出文章中每一个位置的最大匹配距离。

然后定义$f[i]$表示匹配到以$i$结尾的串时,最长的匹配距离。

显然可以二分$L$的取值。

然后容易得到$DP$方程

$f[i]=max(f[i-1],f[j]+i-j)(j<=i-L)$

然后就发现$j$属于一个区间,然后就可以单调队列优化了。

#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define maxn 2200005 namespace SAM{
int last,cnt,go[maxn][2],l[maxn],fa[maxn],n,m,q;
int f[maxn],que[maxn],hd,tl,d[maxn];
char s[maxn];
void init(){last=cnt=1;}
void add(int x)
{
int q,p=last;
if (q=go[p][x])
{
if (l[q]==l[p]+1) last=q;
else
{
int nq=last=++cnt;
l[nq]=l[p]+1;
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q];fa[q]=nq;
for (;go[p][x]==q&&p;p=fa[p]) go[p][x]=nq;
last=nq;
}
}
else
{
int np=last=++cnt; l[np]=l[p]+1;
for (;p&&!go[p][x];p=fa[p]) go[p][x]=np;
if (!p) fa[np]=1;
else
{
q=go[p][x];
if (l[q]==l[p]+1) fa[np]=q;
else
{
int nq=++cnt;l[nq]=l[p]+1;
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq;
}
}
}
}
void ins()
{
last=1;
scanf("%s",s+1); n=strlen(s+1);
F(i,1,n) add(s[i]-'0');
}
bool check(int mid)
{
f[0]=0; tl=0;hd=1;
F(i,1,n)
{
f[i]=f[i-1];int p=i-mid;
if (p>=0)
{
while (hd<=tl&&f[que[tl]]-que[tl]<f[i-mid]-p)tl--;
que[++tl]=p;
}
while (hd<=tl&&que[hd]<i-d[i]) hd++;
if (hd<=tl) f[i]=max(f[i],f[que[hd]]+i-que[hd]);
}
if (f[n]*10>=n*9) return true;
else return false;
}
void dp()
{
scanf("%s",s+1); n=strlen(s+1);
memset(d,0,(n+1)*sizeof(int));
int now=1,t=0;
F(i,1,n)
{
if (go[now][s[i]-'0'])
now=go[now][s[i]-'0'],t++;
else
{
while (now&&!go[now][s[i]-'0']) now=fa[now];
if (!now) now=1,t=0;
else t=l[now]+1,now=go[now][s[i]-'0'];
}
d[i]=t;
}
int l=0,r=n;
while (l<r)
{
int mid=(l+r)/2+1;
if (check(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
}
void solve()
{
init();
scanf("%d%d",&q,&m);
F(i,1,m) ins();
F(i,1,q) dp();
}
} int main()
{
using namespace SAM;
solve();
}

  

BZOJ 2806 [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. BZOJ 2806 [Ctsc2012]Cheat (后缀自动机+二分+单调队列+dp)

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

  4. bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP

    2806: [Ctsc2012]Cheat Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 583  Solved: 330[Submit][Statu ...

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

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

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

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

  7. BZOJ 1010: [HNOI2008]玩具装箱toy | 单调队列优化DP

    原题: http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题解: #include<cstdio> #include<algo ...

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

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

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

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

随机推荐

  1. SC || Chapter7 健壮性和正确性

    finally中语句不论有无异常都执行 若子类重写了父类方法,父类方法没有抛出异常,子类应自己处理全部异常而不再传播:子类从父类继承的方法不能增加或更改异常 判断checked和unchecked: ...

  2. PAT (Basic Level) Practise (中文)- 1011. A+B和C (15)

    http://www.patest.cn/contests/pat-b-practise/1011 给定区间[-231, 231]内的3个整数A.B和C,请判断A+B是否大于C. 输入格式: 输入第1 ...

  3. Bootstrap历练实例:交替的进度条

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  4. C#算术运算符

    一.C#算术运算符 C#语言的算术运算符主要用于数学计算中. 二.示例 using System;using System.Collections.Generic;using System.Linq; ...

  5. ★iOS 性能测试工具 SDK

    一.概括 1. 做一个类似GT的性能测试工具: 2. 第一期主要是CPU.内存功能,要求可以绘制曲线,可以选择曲线区间,自动计算最小值.最大值.均值等,支持曲线全屏显示 目标的视觉效果是类似股票走势图 ...

  6. 函数的扩展——箭头函数this的使用

    箭头函数中的this指向的是定义时的this,而不是执行时的的this . 举例: 案例中,我们的obj对象中有一个属性x和一个属性show( )方法,show( )通过this打印出x的值,结果是u ...

  7. 理解JS闭包的几个小实验

    学了JavaScript有一段时间了,但是对闭包还是不太理解,于是怀着心中的疑问做了几个小实验,终于有点明白了. 首先看一下MDN上的定义:闭包是函数和声明该函数的词法环境的组合. 简单来说,闭包是一 ...

  8. Service Mesh是什么技术

    https://blog.csdn.net/weixin_38044696/article/details/80257488 Service Mesh是什么技术 2018年05月09日 22:07:4 ...

  9. CentOS7安装配置VSFTP

    #是否开启匿名用户,匿名都不安全,不要开 anonymous_enable=NO #允许本机账号登录FTP local_enable=YES #允许账号都有写操作 write_enable=YES # ...

  10. java/jsp执行sql语句的方式

    首先给出sql驱动包 引入sql包 import java.sql.*;//java <%@ page import="java.sql.*"%>//jsp 连接mys ...