题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2806

只想着怎么用后缀数据结构做,其实应该考虑结合其他算法。

可以二分那个长度 L 。设当前二分为 mid ;令 dp[ i ] 表示到 i 位置“熟悉”的最大长度。那么 \( dp[i]=\max(dp[i-1],\max\limits_{j<=i-mid,s[j+1...i] \in S}(dp[j]+(i-j)) ) \) (其中 S 是模式串的所有子串集合)。

关于那个判断,只要先作出以询问串的每个位置 i 为结尾最长能匹配的后缀长度 f[ i ] 就行了。

这个 DP 过程可以用单调队列优化。在 i 位置把 i-mid 的值加入队列。

注意匹配的长度不是自动机对应点的 len ,而是要记一个 ct ,如果顺延的话,ct++ 而不是 ct = len[ go[cr][w] ] 这样。

注意 dp 的时候如果 i < mid ,不仅是不往队列加元素,还不能做转移(比如 s[ 1...i ] 在模式串里出现也不能给 dp[ i ] 赋值)!因为这样匹配上的是长度 <mid 的,不合法。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int Mx(int a,int b){return a>b?a:b;}
const int N=11e5+;
int n,m,go[N][],len[N],fa[N],cnt=,lst;
int f[N],dp[N],q[N],he,tl; char s[N];
int cz(int p,int w)
{
int q=go[p][w],nq=++cnt; len[nq]=len[p]+;
fa[nq]=fa[q]; fa[q]=nq;
memcpy(go[nq],go[q],sizeof go[q]);
for(;go[p][w]==q;p=fa[p])go[p][w]=nq;
return nq;
}
int ins(int p,int w)
{
if(go[p][w])
{
int q=go[p][w];
if(len[q]==len[p]+)return q;
return cz(p,w);
}
int np=++cnt; len[np]=len[p]+;
for(;p&&!go[p][w];p=fa[p])go[p][w]=np;
if(!p){ fa[np]=;return np;}//fa=1!
int q=go[p][w];
if(len[q]==len[p]+)fa[np]=q; else fa[np]=cz(p,w);
return np;
}
int chk(int mid,int d)
{
he=tl=;
for(int i=;i<=d;i++)
{
dp[i]=dp[i-];
if(i<mid)continue;//not do!!!
int cr=i-mid;
while(he<tl&&dp[q[tl]]-q[tl]<=dp[cr]-cr)tl--;
q[++tl]=cr;
while(he<tl&&q[he+]<i-f[i])he++;
if(he<tl)dp[i]=Mx(dp[i],dp[q[he+]]+i-q[he+]);
}
return dp[d];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%s",s+);
for(int j=,lm=strlen(s+),d=;j<=lm;j++)
d=ins(d,s[j]-'');
}
for(int i=,d;i<=n;i++)
{
scanf("%s",s+);
d=strlen(s+);
for(int j=,cr=,ct=;j<=d;j++)//ct not len[cr]!!
{
int w=s[j]-'';
while(!go[cr][w])cr=fa[cr],ct=len[cr];
if(go[cr][w])cr=go[cr][w],ct++;
else cr=,ct=;
f[j]=ct;
}
int lm=ceil(0.9*d),l=,r=d,ret=;
while(l<=r)
{
int mid=l+r>>;
if(chk(mid,d)>=lm)ret=mid,l=mid+;
else r=mid-;
}
printf("%d\n",ret);
}
return ;
}

bzoj 2806 [Ctsc2012]Cheat——广义后缀自动机+单调队列优化DP的更多相关文章

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

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

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

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

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

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

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

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

  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. BZOJ 2442 [Usaco2011 Open]修剪草坪:单调队列优化dp

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2442 题意: 有n个数a[i]从左到右排成一排. 你可以任意选数,但是连续的数不能超过k个 ...

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

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

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

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

随机推荐

  1. Linux:NFS配置

    NFS配置 1.创建分享的文件:touch /var/www/html/aa.txt2.查看是否安装NFS:rpm -qa|grep nfs3.查看IP地址:ifconfig4.配置NFS:vi /e ...

  2. subprocess(子进程模块)

    subprocess: 子进程模块 一个正在运行的程序叫做进程 一个进程 开启了另一个进程 这个被开启的程序叫做子ka进程 ###########################在cmd中执行#### ...

  3. 性能测试-2.Fiddler抓包工具的使用

    Fiddler基础知识(此文原文地址) Fiddler是强大的抓包工具,它的原理是以web代理服务器的形式进行工作的,使用的代理地址是:127.0.0.1,端口默认为8888,我们也可以通过设置进行修 ...

  4. 【转载】 看996ICU

    原文地址: https://www.jianshu.com/p/15d8726fa8a8 作者:Demisstif 来源:简书 ------------------------------------ ...

  5. Anaconda 的基本使用

    Anaconda常用的Python版本管理工具和Python包管理软件,conda是Anaconda中的具体管理工具,下载地址为: https://www.anaconda.com/distribut ...

  6. 螺旋图 comet3 (comet) 不同轴的圆周运动图

    matlab 绘图 螺旋图小实例  动态显示comet3函数(comet显示平面) t=[:]; x=*t*sin(pi/).*cos(*t); y=*t*sin(pi/).*sin(*t); z=* ...

  7. CodeForces - 441D: Valera and Swaps(置换群)

    A permutation p of length n is a sequence of distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n). A permu ...

  8. xdoj-1022-A simple math problem 2 // 太强了

    //其实题目中f[n]的值可理解为存在多少个整数对使a*b<=n #include<cstdio> #define N 1007 #define maxn 1000005 using ...

  9. lecture4特征提取-七月在线-cv

    霍夫变换 http://blog.csdn.net/sudohello/article/details/51335237 http://blog.csdn.net/glouds/article/det ...

  10. 《DSP using MATLAB》Problem5.23

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% O ...