题目

好题啊

\(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. DB Intro - MongoDB Relations

    https://www.quackit.com/mongodb/tutorial/mongodb_create_a_relationship.cfm

  2. Basic Data Structures and Algorithms in the Linux Kernel--reference

    http://luisbg.blogalia.com/historias/74062 Thanks to Vijay D'Silva's brilliant answer in cstheory.st ...

  3. Oracle新手常遇到的问题

    1.问题描述:尝试加载 Oracle 客户端库时引发 BadImageFormatException.如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题. 解决方 ...

  4. mysql应用学习-解决数据乱码

    原因 mysql数据库character_set_database和character_set_server默认编码是latin1,所以导致乱码: 修改步骤 step1. 修改my.ini配置 在[m ...

  5. C# 在窗体的子线程中创建新窗体

    在子线程中如果简单的调用新窗体的话,新出来的窗体会直接一闪而过.没有停留.效果很差 具体解决方法 如下: 在母窗体中建立委托 public delegate void setShowChartForm ...

  6. 【学习笔记】Java实用类:枚举(Enum)

    Java API(Java Application Programming Interface)Java应用程序编程接口... 实用类:Java API提供了几个常用包: 1.java.lang:编写 ...

  7. hdu 1520 树形DP基础

    http://acm.hdu.edu.cn/showproblem.php?pid=1520 父节点和子节点不能同时选. http://blog.csdn.net/woshi250hua/articl ...

  8. Django之(URL)路由系统

    路由系统 简而言之,django的路由系统作用就是使views里面处理数据的函数与请求的url建立映射关系.使请求到来之后,根据urls.py里的关系条目,去查找到与请求对应的处理方法,从而返回给客户 ...

  9. stark——pop功能(admin中添加功能)

    一.pop功能需要实现的功能和问题 1.如何在一对多和多对多字段后渲染 +2.+对应的跳转路径是什么3.保存添加记录同时,将原页面的对应的下拉菜单中添加该记录 二.window.open()方法详解 ...

  10. php有经纬度计算距离

    /** *  @desc 根据两点间的经纬度计算距离 *  @param float $lat 纬度值 *  @param float $lng 经度值 */  function getDistanc ...