题意:

Description

Input

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

Output

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

HINT

输入文件不超过1100000字节

注意:题目有改动,可识别的长度不小于90%即可,而不是大于90%

题解:

好题!

先对标准作文库建出广义SAM,把每个作文串在SAM上匹配,求出每一位之前最长出现过子串长度$s[i]$;

显然没有什么好办法直接求L,考虑二分答案判断是否可行;

设当前二分值为$mid$,$f[i]$表示前$i$位最长的熟悉长度,则易得DP方程:$f[i]=max\{f[j]+i-j\}$,决策区间就是$[i-s[i],i-mid]$;

显然$i-s[i]$单调不降,所以可以用单调队列优化到$O(n)$

最后判一下比例是否大于$90\%$即可。

代码:

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
using namespace std;
typedef long long ll;
typedef double db;
int n,m,l,r,ans,len,tot=,last,rt=,son[][],fa[],mx[],s[],q[],f[];
char st[];
void extend(int ch){
int p=last,np=++tot;
mx[np]=mx[p]+;
for(;p&&!son[p][ch];p=fa[p])son[p][ch]=np;
if(!p)fa[np]=rt;
else{
int q=son[p][ch];
if(mx[q]==mx[p]+)fa[np]=q;
else{
int nq=++tot;
mx[nq]=mx[p]+;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for(;p&&son[p][ch]==q;p=fa[p])son[p][ch]=nq;
}
}
last=np;
}
void pre(char *st,int len){
int nw=rt,tmp=;
for(int i=;i<=len;i++){
if(son[nw][st[i]-'']){
nw=son[nw][st[i]-''];
tmp++;
}else{
for(;nw&&!son[nw][st[i]-''];nw=fa[nw]);
if(!nw){
nw=rt;
tmp=;
}else{
tmp=mx[nw]+;
nw=son[nw][st[i]-''];
}
}
s[i]=tmp;
}
}
bool check(int k){
int L=,R=;
for(int i=;i<=len;i++){
f[i]=f[i-];
if(i<k)continue;
for(;L<=R&&f[q[R]]-q[R]<f[i-k]-i+k;R--);
q[++R]=i-k;
for(;L<=R&&q[L]<i-s[i];L++);
if(L<=R)f[i]=max(f[i],f[q[L]]-q[L]+i);
}
return f[len]*>=len*;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
scanf("%s",st+);
len=strlen(st+);
last=rt;
for(int j=;j<=len;j++){
extend(st[j]-'');
}
}
for(int i=;i<=n;i++){
scanf("%s",st+);
len=strlen(st+);
pre(st,len);
l=ans=,r=len;
while(l<=r){
int mid=(l+r)/;
if(check(mid))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】Cheat 【广义后缀自动机+单调队列优化dp+二分】

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. jre1.6下载地址

    官方下载地址http://java.sun.com/javase/downloads/widget/jdk6.jsp

  2. hdu 3352 求边双联通分量模板题(容器)

    /*这道题是没有重边的,求加几条边构成双联通,求边联通分量,先求出桥然后缩点,成一个棵树 找叶子节点的个数*/ #include<stdio.h> #include<string.h ...

  3. MYSQL 技术内幕 博客学习

    http://blog.csdn.net/CCyutaotao/article/category/6147849/3

  4. 怎样又一次编译linux内核

    linux作为自由软件.在广大爱好者的支持下,内核版本号不断更新. 新的内核修订了就得内核的bug,并添加了很多新的特性.假设用户须要使用这些新的特性或者依据自己的系统量身定做一个更高效或更稳定的内核 ...

  5. PL SQL Developer client 连接server

    安装完Oracle,PLSQL之后,在server中打开监听. 计算机右键-管理-服务和应用程序-服务-打开以Oracle开头的服务,特别是监听,这个最重要.详细如图所看到的. (1)配置监听的位置 ...

  6. Wannafly挑战赛25 C 期望操作数 数学

    题目 题意:给你你一个数x和一个数q,x<=q,每一次可以等概率把x变成[x,q]中任意一个数,问变成q的步数的期望,输出对998244353取模,多组询问 题解:首先肯定的是,可以预处理,因为 ...

  7. 线段树(1)——点修改&建树

    #include<cstdio> #include<algorithm> using namespace std; #define MAX 10000 #define INF ...

  8. postgresql 常规操作以及检查备份

    一.建表时,复制源表的信息test=# test=# \d test.t1 Table "test.t1" Column | Type | Collation | Nullable ...

  9. 在量化金融中15个最流行的Python数据分析库

    Python是当今应用最广泛的编程语言之一,以其效率和代码可读性著称.作为一个科学数据的编程语言,Python介于R和java之间,前者主要集中在数据分析和可视化,而后者主要应用于大型应用.这种灵活性 ...

  10. Dalvik虚拟机和JVM的对比

    Dalvik虚拟机与Java虚拟机有着很多相似的特性,都支持GC,JIT,JNI等等.其主要区别在于文件格式以及指令集不同,下面对两者的特性进行比较与讨论. Difference1:文件格式 Dalv ...