题目

好题啊

\(SAM\)+单调队列优化\(dp\)

首先这个\(L\)满足单调性真是非常显然我们可以直接二分

二分之后套一个\(dp\)就好了

设\(dp[i]\)表示到达\(i\)位置熟悉的文章的最大长度

有一个非常显然的\(dp\)方程

\[dp_i=max\{dp_j+i-j\}\ (i-j>=mid)
\]

同时\([j+1,i]\)这个子串也得是模式串里的一个子串

对于上面那个\(dp\)方程,我们把\(i\)提出来,用单调队列维护一下\(dp_j-j\)的最大值就好了

下面这个限制条件的话,我们可以处理出以\(i\)这个位置的为结尾的和所有的模式串的最长公共子串的长度\(mx[i]\)

这个处理的话我们直接在\(SAM\)上过一遍就好了

之后我们就有了第二个限制

\[j>=i-mx[i]
\]

经过分析我们可以发现\(i\)每次稳定加\(1\),而\(mx[i]\)每次最多加\(1\),所以\(i-mx[i]\)是单调不降的的

于是我们还是可以用单调队列来维护

复杂度\(O(Tnlogn)\)

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 2000010
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
char S[maxn];
int fa[maxn<<1],len[maxn<<1],son[maxn<<1][3];
int mx[maxn];
int q[maxn],dp[maxn];
int T,m,n,cnt=1,lst=1;
inline void ins(int c)
{
int f=lst,p=++cnt; lst=p;
len[p]=len[f]+1;
while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
if(!f) {fa[p]=1;return;}
int x=son[f][c];
if(len[f]+1==len[x]) {fa[p]=x;return;}
int y=++cnt;
len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
for(re int i=0;i<3;i++) son[y][i]=son[x][i];
while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
}
inline void query()
{
int now=1,L=0;
for(re int i=1;i<=n;i++)
{
if(son[now][S[i]-'0']) {mx[i]=++L;now=son[now][S[i]-'0'];continue;}
while(now&&!son[now][S[i]-'0']) now=fa[now];
if(!now) {mx[i]=L=0;now=1;continue;}
L=len[now]+1,mx[i]=L;now=son[now][S[i]-'0'];
}
}
inline int check(int mid)
{
int h=1,t=0;
for(re int i=0;i<=n;i++) q[i]=dp[i]=0;
for(re int i=mid;i<=n;i++)
{
while(h<=t&&dp[i-mid]-i+mid>dp[q[t]]-q[t]) t--;
q[++t]=i-mid;
while(h<=t&&i-mx[i]>q[h]) h++;
if(h<=t) dp[i]=i+dp[q[h]]-q[h];
dp[i]=max(dp[i],dp[i-1]);
}
if(dp[n]*10>=n*9) return 1;
return 0;
}
int main()
{
scanf("%d%d",&T,&m);
for(re int i=1;i<=m;i++)
{
scanf("%s",S+1); int L=strlen(S+1);
for(re int j=1;j<=L;j++) ins(S[j]-'0');
ins(2);
}
while(T--)
{
scanf("%s",S+1),n=strlen(S+1);
query();
int l=1,r=n,ans=0;
while(l<=r)
{
int mid=l+r>>1;
if(check(mid)) ans=mid,l=mid+1;else r=mid-1;
}
printf("%d\n",ans);
}
return 0;
}

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

  1. P4022 [CTSC2012]熟悉的文章

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

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

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

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

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

  4. 题解-CTSC2012 熟悉的文章

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

  5. CTSC2012 熟悉的文章

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

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

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

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

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

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

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

  9. Luogu-4022 [CTSC2012]熟悉的文章

    广义后缀自动机+DP 对于作文库建出广义后缀自动机,广义自动机就是在每次添加一个字符串之前把\(last=0\),然后正常添加就好了 对于每个询问串,预处理出每个位置\(i\)能向前匹配的最长长度\( ...

随机推荐

  1. 字符型图片验证码,使用tensorflow实现卷积神经网络,进行验证码识别CNN

    本项目使用卷积神经网络识别字符型图片验证码,其基于 TensorFlow 框架.它封装了非常通用的校验.训练.验证.识别和调用 API,极大地减低了识别字符型验证码花费的时间和精力. 项目地址: ht ...

  2. jvm双亲委派模型

    其实,双亲委派模型并不复杂.自定义类加载器也不难!随便从网上搜一下就能搜出一大把结果,然后copy一下就能用.但是,如果每次想自定义类加载器就必须搜一遍别人的文章,然后复制,这样显然不行.可是自定义类 ...

  3. DP Intro - Tree DP

    二叉苹果树 题目 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点 ...

  4. 图解 TCMalloc

    https://zhuanlan.zhihu.com/p/29216091 图解 TCMalloc hellocode 永远年轻   693 人赞了该文章 前言 TCMalloc 是 Google 开 ...

  5. 客户端与服务器cookie

    认识cookie 第一部分: 概要 cookie是一种早期使用的客户端存储机制(现在仍在广泛使用),cookie数据会在Web浏览器和Web服务器之间传输, 因为早期cookie是针对服务器脚本设计的 ...

  6. 在使用反射时,maven设置依赖范围引起的异常

    背景是,运用annotation进行权限控制,将一个包下面的类.进行反射,然后判断类的annotation,根据annotation设置权限 问题来了,包下面有5个类,在反射时报了 javqx.ser ...

  7. 记一次MongoDB性能问题

    下面文章转载自火丁笔记,原作者描述了一次MongoDB数据迁移过程中遇到的性能问题及其解决方案,中间追查问题的方法和工具值得我们学习.下面是其原文: 最近忙着把一个项目从MySQL迁移到MongoDB ...

  8. 关于两个 IQueryable 合并

    原先根据需求要对数据进行两种筛选,起初写过滤条件,但是过滤后发现有的数据重叠.因此改为查询两次. 因为查询后返回的是两个相同的.匿名的 IQueryable ,最终的目的是想两个 类型结合成一个. 参 ...

  9. 嵌入式Tomcat Web服务器的使用

    在运行web工程时,常常要频繁启动tomcat,使用嵌入式tomcat可以减少部分重复操作. 1.下载tomcat5.0.28embed.zip 解压文件夹复制到工程下. http://archive ...

  10. pythion的定义函数和传递实参

    1.定义函数 例子: def greet_user(): """显示简单的问候语""" print("Hello!")g ...