题目

好题啊

\(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. Activemq API使用(不整合spring)

    首先需要引入activemq的jar包,这里用的是5.14.4版本的 <!-- https://mvnrepository.com/artifact/org.apache.activemq/ac ...

  2. 【3dsMax安装失败,如何卸载、安装3dMax 2010?】

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  3. Django From表单定制

    参考文档: Forms The Forms API Working with forms 一.简单的Form表达定制 1)首先我们得定制Form表单类,下面我们创建一个简单的类: class Book ...

  4. 使用urllib和http.cookiejar获取python老男孩学员成绩

    打开http://crm.oldboyedu.com/crm/grade/single/ 鼠标右键查看源代码,可以看到我们需要post的name.如下: 这里需要在post试提交token和searc ...

  5. 第十六章:自定义push notification sound

    前面一节已经讲过如何在ionic中集成jpush,这样我们的hybrid app在部署到ios或者android上面的时候,就可以接收通知了.如果不满足系统自带的声音,可以通过一些方式来播放自定义的通 ...

  6. bzoj 5308: [Zjoi2018]胖

    Description Cedyks是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公. Cedyks是一个富有的男孩子.他住在著名的ThePLace(宫殿)中. Cedyks是一个 ...

  7. 深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP

    前言 Bob大叔提出并发扬了S.O.L.I.D五大原则,用来更好地进行面向对象编程,五大原则分别是: The Single Responsibility Principle(单一职责SRP) The ...

  8. Java日志框架解析及实战分析

    转载自: https://zhuanlan.zhihu.com/p/24272450 https://zhuanlan.zhihu.com/p/24275518 作为Java程序员,幸运的是,Java ...

  9. JavaScript数组求和

    <script> function demo(){ var d=document.getElementsByTagName("input")[0].value.spli ...

  10. Matlab GUI选项卡

    1.在这个网址下载一个工具包,里面应该有四个文件:tabselectionfcp.p.tabselectionfcn.m.tabpanel.p和tabpanel.m,显然代码用.p格式进行加密了. 2 ...