题意

显然这个\(L\)是可以二分的,我们只需要判断\(L\)是否合法即可。

显然有一个\(O(n^2)\)的DP:

设\(f_i\)表示当前匹配到\(i\)的最大匹配长度。

\(f_i=max(f_j+i-(j+1)+1)\ j\in[i-match_i,i-L]\)

其中的\(match_i\)表示前缀\(i\)能和文本库匹配的最长后缀长度,这显然是可以在后缀自动机上匹配求出的。

于是就可以\(O(n^2logn)\)做了。

发现\(i-match_i\)单调递增,于是可以单调队列解决。

证明:

反证即可,如果不单调必定是如下情况:



红线是i匹配的长度,蓝线是i+1匹配的长度,显然i能匹配更长。

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2*1e6+10;
int n,m;
int match[maxn],f[maxn],q[maxn];
char s[maxn];
struct SAM
{
int last,tot;
int fa[maxn],len[maxn];
int ch[maxn][2];
SAM(){last=tot=1;}
inline void add(int c)
{
if(ch[last][c]&&len[last]+1==len[ch[last][c]]){last=ch[last][c];return;}
int now=++tot;len[now]=len[last]+1;
int p=last;
while(p&&!ch[p][c])ch[p][c]=now,p=fa[p];
if(!p){fa[now]=1;last=now;return;}
int q=ch[p][c];bool flag=0;
if(len[q]==len[p]+1)fa[now]=q;
else
{
if(p==last)flag=1;
int nowq=++tot;len[nowq]=len[p]+1;
memcpy(ch[nowq],ch[q],sizeof(ch[q]));
fa[nowq]=fa[q],fa[q]=fa[now]=nowq;
while(p&&ch[p][c]==q)ch[p][c]=nowq,p=fa[p];
if(flag)last=nowq;
}
if(!flag)last=now;
}
}sam;
inline void getmatch(char* s)
{
int len=strlen(s+1),now=1,nowl=0;
for(int i=1;i<=len;i++)
{
while(now&&!sam.ch[now][s[i]-'0'])now=sam.fa[now],nowl=sam.len[now];
if(now)now=sam.ch[now][s[i]-'0'],nowl++;
else now=1,nowl=0;
match[i]=nowl;
}
}
inline bool check(int mid,char* s)
{
int l=1,r=0,len=strlen(s+1);
for(int i=0;i<mid;i++)f[i]=0;
for(int i=mid;i<=len;i++)
{
f[i]=f[i-1];
while(l<=r&&f[q[r]]-q[r]<=f[i-mid]-(i-mid))r--;
q[++r]=i-mid;
while(l<=r&&q[l]<i-match[i])l++;
if(l<=r)f[i]=max(f[i],i+f[q[l]]-q[l]);
}
return f[len]*10>=len*9;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
sam.last=1;
scanf("%s",s+1);
int len=strlen(s+1);
for(int j=1;j<=len;j++)sam.add(s[j]-'0');
}
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
getmatch(s);
int l=0,r=strlen(s+1),ans=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid,s))ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
}
return 0;
}

luoguP4022 [CTSC2012]熟悉的文章的更多相关文章

  1. P4022 [CTSC2012]熟悉的文章

    题目 P4022 [CTSC2012]熟悉的文章 题目大意:多个文本串,多个匹配串,我们求\(L\),\(L\)指(匹配串中\(≥L\)长度的子串出现在文本串才为"熟悉",使得匹配 ...

  2. [CTSC2012]熟悉的文章(后缀自动机+动态规划)

    题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么觉得熟悉,仿佛是某些范 ...

  3. 【[CTSC2012]熟悉的文章】

    题目 好题啊 \(SAM\)+单调队列优化\(dp\) 首先这个\(L\)满足单调性真是非常显然我们可以直接二分 二分之后套一个\(dp\)就好了 设\(dp[i]\)表示到达\(i\)位置熟悉的文章 ...

  4. [BZOJ2806][CTSC2012]熟悉的文章(Cheat)

    bzoj luogu 题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么 ...

  5. 题解-CTSC2012 熟悉的文章

    Problem bzoj 题目大意:给定多个标准串和一个文本串,全部为01串,如果一个串长度不少于\(L\)且是任意一个标准串的子串,那么它是"熟悉"的.对于文本串\(A\),把\ ...

  6. CTSC2012 熟悉的文章

    传送门 首先很容易想到对于所有的模式串建出广义后缀自动机,之后对于我们每一个要检查的文本串,先在SAM上跑,计算出来每一个位置能匹配到的最远的位置是多少.(就是当前点减去匹配长度) 之后--考虑DP- ...

  7. Luogu4022 CTSC2012 熟悉的文章 广义SAM、二分答案、单调队列

    传送门 先将所有模板串扔进广义SAM.发现作文的\(L0\)具有单调性,即\(L0\)更小不会影响答案,所以二分答案. 假设当前二分的值为\(mid\),将当前的作文放到广义SAM上匹配. 设对于第\ ...

  8. [CTSC2012]熟悉的文章 (后缀自动机 单调队列)

    /* 首先答案显然是具有单调性的, 所以可以二分进行判断 然后当我们二分过后考虑dp来求最长匹配个数, 发现每个点能够转移的地点 肯定是一段区间, 然后这样就能够得到一个log^2算法 至于每个点的匹 ...

  9. [CTSC2012]熟悉的文章 后缀自动机

    题面:洛谷 题解: 观察到L是可二分的,因此我们二分L,然后就只需要想办法判断这个L是否可行即可. 因为要尽量使L可行,因此我们需要求出对于给定L,这个串最多能匹配上多少字符. 如果我们可以对每个位置 ...

随机推荐

  1. centos7 laravel 项目 npm install报错

    npm install 初始化项目依赖的前端资源   报错 ERR xxx .. socket,symbol link is not supported ... 如果报错了 重新npm install ...

  2. 番茄助手 最新 Visual Assist X 适应于VS2019 VS2017 VS2015 VS2013 亲测可用

    番茄助手 最新 Visual Assist X 适应于VS2019 VS2017 VS2015 VS2013 亲测可用 如图: 颜色已经改变: 下载说明: /* INSTALLATION 0) Uni ...

  3. 网页添加Live2D看板娘简易教程

    看板娘是一种职业和习惯称呼,也是ACGN次文化中的萌属性之一.简而言之就是小店的女服务生,也有“吸引顾客,招揽生意,提高人气”等作用类似品牌形象代言人的含义. 如果想在自己的博客上放一个呆萌的看板娘非 ...

  4. webpack css模块化和ant-design按需加载冲突

    其实具体出现了什么问题,我也记得不清楚了,今天突然回想起来必须记录一下,一个思想就是用exclude将node_module目录下的文件排除,网上有很多相关例子,但不知是不是因为时间久远,都不生效,无 ...

  5. C语言复习上

    通常开始学习C语言的时候,第一句写的就是"helloword" int main(){ printf("hello word"); } 接下来的日子里需要注意的 ...

  6. java全栈项目

    文档地址:https://course.7yue.pro/lin/sleeve/ http://talelin.unna.com.cn/ 1.小程序里,我把结构分为三部分:wxml(view).pag ...

  7. 进制转换器V1.0_Beta

    一.截图部分 二.代码部分: char2num() 作用:将字符转化成对应的数字        e.g.   '9'->9    'A'->10 int char2num(char ch) ...

  8. MySQL 优化 (三)

    参数优化 query_cache_size (1) 简介: 查询缓存简称QC,使用查询缓冲,mysql将查询结果存放在缓冲区中,今后对于同样的select语句(区分大小写),将直接从缓冲区中读取结果. ...

  9. IDE开发小技巧-快速引包/替换关键词

    快速引包 Ctrl+Shift+O 快速搜索/查找替换   Ctrl+F

  10. 基于python的yaml配置文件使用方法

    一.介绍 YAML是一种简洁的非标记语言 YAML以数据为中心,使用空白.缩进.分行组织数据,从而使表达更加简洁易懂 二.基本规则 大小写敏感 使用缩进表示层级关系 禁止使用Tab缩进,只能使用空格键 ...