【[CTSC2012]熟悉的文章】
好题啊
\(SAM\)+单调队列优化\(dp\)
首先这个\(L\)满足单调性真是非常显然我们可以直接二分
二分之后套一个\(dp\)就好了
设\(dp[i]\)表示到达\(i\)位置熟悉的文章的最大长度
有一个非常显然的\(dp\)方程
\]
同时\([j+1,i]\)这个子串也得是模式串里的一个子串
对于上面那个\(dp\)方程,我们把\(i\)提出来,用单调队列维护一下\(dp_j-j\)的最大值就好了
下面这个限制条件的话,我们可以处理出以\(i\)这个位置的为结尾的和所有的模式串的最长公共子串的长度\(mx[i]\)
这个处理的话我们直接在\(SAM\)上过一遍就好了
之后我们就有了第二个限制
\]
经过分析我们可以发现\(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]熟悉的文章】的更多相关文章
- P4022 [CTSC2012]熟悉的文章
题目 P4022 [CTSC2012]熟悉的文章 题目大意:多个文本串,多个匹配串,我们求\(L\),\(L\)指(匹配串中\(≥L\)长度的子串出现在文本串才为"熟悉",使得匹配 ...
- [CTSC2012]熟悉的文章(后缀自动机+动态规划)
题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么觉得熟悉,仿佛是某些范 ...
- [BZOJ2806][CTSC2012]熟悉的文章(Cheat)
bzoj luogu 题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么 ...
- 题解-CTSC2012 熟悉的文章
Problem bzoj 题目大意:给定多个标准串和一个文本串,全部为01串,如果一个串长度不少于\(L\)且是任意一个标准串的子串,那么它是"熟悉"的.对于文本串\(A\),把\ ...
- CTSC2012 熟悉的文章
传送门 首先很容易想到对于所有的模式串建出广义后缀自动机,之后对于我们每一个要检查的文本串,先在SAM上跑,计算出来每一个位置能匹配到的最远的位置是多少.(就是当前点减去匹配长度) 之后--考虑DP- ...
- Luogu4022 CTSC2012 熟悉的文章 广义SAM、二分答案、单调队列
传送门 先将所有模板串扔进广义SAM.发现作文的\(L0\)具有单调性,即\(L0\)更小不会影响答案,所以二分答案. 假设当前二分的值为\(mid\),将当前的作文放到广义SAM上匹配. 设对于第\ ...
- [CTSC2012]熟悉的文章 (后缀自动机 单调队列)
/* 首先答案显然是具有单调性的, 所以可以二分进行判断 然后当我们二分过后考虑dp来求最长匹配个数, 发现每个点能够转移的地点 肯定是一段区间, 然后这样就能够得到一个log^2算法 至于每个点的匹 ...
- [CTSC2012]熟悉的文章 后缀自动机
题面:洛谷 题解: 观察到L是可二分的,因此我们二分L,然后就只需要想办法判断这个L是否可行即可. 因为要尽量使L可行,因此我们需要求出对于给定L,这个串最多能匹配上多少字符. 如果我们可以对每个位置 ...
- Luogu-4022 [CTSC2012]熟悉的文章
广义后缀自动机+DP 对于作文库建出广义后缀自动机,广义自动机就是在每次添加一个字符串之前把\(last=0\),然后正常添加就好了 对于每个询问串,预处理出每个位置\(i\)能向前匹配的最长长度\( ...
随机推荐
- 字符型图片验证码,使用tensorflow实现卷积神经网络,进行验证码识别CNN
本项目使用卷积神经网络识别字符型图片验证码,其基于 TensorFlow 框架.它封装了非常通用的校验.训练.验证.识别和调用 API,极大地减低了识别字符型验证码花费的时间和精力. 项目地址: ht ...
- jvm双亲委派模型
其实,双亲委派模型并不复杂.自定义类加载器也不难!随便从网上搜一下就能搜出一大把结果,然后copy一下就能用.但是,如果每次想自定义类加载器就必须搜一遍别人的文章,然后复制,这样显然不行.可是自定义类 ...
- DP Intro - Tree DP
二叉苹果树 题目 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点 ...
- 图解 TCMalloc
https://zhuanlan.zhihu.com/p/29216091 图解 TCMalloc hellocode 永远年轻 693 人赞了该文章 前言 TCMalloc 是 Google 开 ...
- 客户端与服务器cookie
认识cookie 第一部分: 概要 cookie是一种早期使用的客户端存储机制(现在仍在广泛使用),cookie数据会在Web浏览器和Web服务器之间传输, 因为早期cookie是针对服务器脚本设计的 ...
- 在使用反射时,maven设置依赖范围引起的异常
背景是,运用annotation进行权限控制,将一个包下面的类.进行反射,然后判断类的annotation,根据annotation设置权限 问题来了,包下面有5个类,在反射时报了 javqx.ser ...
- 记一次MongoDB性能问题
下面文章转载自火丁笔记,原作者描述了一次MongoDB数据迁移过程中遇到的性能问题及其解决方案,中间追查问题的方法和工具值得我们学习.下面是其原文: 最近忙着把一个项目从MySQL迁移到MongoDB ...
- 关于两个 IQueryable 合并
原先根据需求要对数据进行两种筛选,起初写过滤条件,但是过滤后发现有的数据重叠.因此改为查询两次. 因为查询后返回的是两个相同的.匿名的 IQueryable ,最终的目的是想两个 类型结合成一个. 参 ...
- 嵌入式Tomcat Web服务器的使用
在运行web工程时,常常要频繁启动tomcat,使用嵌入式tomcat可以减少部分重复操作. 1.下载tomcat5.0.28embed.zip 解压文件夹复制到工程下. http://archive ...
- pythion的定义函数和传递实参
1.定义函数 例子: def greet_user(): """显示简单的问候语""" print("Hello!")g ...