题目链接:Cheat

  话说这道题很久以前某人就给我们考过,直到现在,我终于把这个坑填上了……

  这道题要我们把一个串\(S\)划分成若干块,每块长度不小于\(L_0\),使得能够在文章库中完全匹配的块的长度和占总长度的\(90\%\)以上。首先,答案显然是可以二分的。于是,我们就可以二分一个答案\(ans\),考虑如何\(check\)。

  很显然的一个想法就是\(dp\)。如果我们知道这个串的第\(i\)位往前最多能够走\(x_i\)位,使得\(S_{i-x_i}\)到\(S_i\)组成的串能够在文章库中匹配,那么我们就可以写出\(dp\)方程了:\begin{aligned} f_i=&\max \{ f_j+i-j \}(i-x_i \le j \le i-ans) \\ = &i+\max \{ f_i-j \}\ (i-x_i \le j \le i-ans) \end{aligned}

  当然,\(f_i=\max(f_i,f_{i-1})\)

  然后,我们就可以发现\(i-x_i\)是单调的(话说我刚开始还没有看出来),然后由于\(i-ans\)显然也是单调的,所以我们就可以弄个单调队列维护区间最大值即可。最后再判断一下总的匹配长度是否大于等于总长度的\(90\%\)即可。

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 2200010 using namespace std;
typedef long long llg; int n,m,tot,last,f[maxn>>1],L,pi[maxn>>1];
int son[maxn][2],fa[maxn],len[maxn],d[maxn>>1],ld,rd;
char s[maxn>>1]; void add(int p,int x){
int np=++tot; len[np]=len[p]+1,fa[np]=p; last=np;
for(;p && !son[p][x];p=fa[p]) son[p][x]=np;
if(!p) fa[np]=1;
else{
int q=son[p][x];
if(len[q]==len[p]+1) fa[np]=q;
else{
int nq=++tot;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q]; fa[q]=fa[np]=nq; len[nq]=len[p]+1;
for(;son[p][x]==q;p=fa[p]) son[p][x]=nq;
}
}
} bool check(int x){
ld=rd=0;
for(int i=1;i<=L;i++){f[i]=f[i-1];
if(i>=x){
while(ld<rd && f[d[rd-1]]-d[rd-1]<=f[i-x]-i+x) rd--;
d[rd++]=i-x;
}
while(ld<rd && d[ld]<i-pi[i]) ld++;
if(ld<rd) f[i]=max(f[i],f[d[ld]]-d[ld]+i);
}
return f[L]*10>=9*L;
} int main(){
File("a");
scanf("%d %d",&n,&m); tot=1;
for(int i=1,l;i<=m;i++){
scanf("%s",s+1);
last=1; l=strlen(s+1);
for(int j=1;j<=l;j++) add(last,s[j]-'0');
}
for(int i=1,l,r,mid;i<=n;i++){
scanf("%s",s+1);
l=0; L=r=strlen(s+1);
for(int j=1,p=1,le=0;j<=L;j++){
while(p!=1 && !son[p][s[j]-'0']) p=fa[p],le=len[p];
if(son[p][s[j]-'0']) p=son[p][s[j]-'0'],le++; pi[j]=le;
}
while(l!=r){
mid=(l+r+1)>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
}
return 0;
}

BZOJ 2806 【CTSC2012】 Cheat的更多相关文章

  1. 【BZOJ2806】【CTSC2012】Cheat 广义后缀自动机+二分+Dp

    题目 题目在这里 思路&做法 我们先对标准作文库建广义后缀自动机. 然后对于每一篇阿米巴的作文, 我们首先把放到广义后缀自动机跑一遍, 对于每一个位置, 记录公共子串的长度\((\)即代码和下 ...

  2. 【BZOJ2806】【CTSC2012】Cheat - 广义后缀自动机+单调队列优化DP

    题意: Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 Output N行 ...

  3. 【BZOJ2806】Cheat(后缀自动机,二分答案,动态规划,单调队列)

    [BZOJ2806]Cheat(后缀自动机,二分答案,动态规划,单调队列) 题面 BZOJ 洛谷 题解 很有趣的一道题啊 对于在所有的串上面进行匹配? 很明显的后缀自动机 所以先构建出广义后缀自动机 ...

  4. BZOJ 1854 【Scoi2010】 游戏

    Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性 ...

  5. BZOJ 1303 【CQOI2009】中位数图

    baidu了一下bzoj水题列表...找到这道题.   题目大意:给定一个数t,在给定的一段包含1-n的序列中找出多少个长度为奇数子序列的中位数为t. 第一眼没看数据范围,于是开心的打了一个O(n^3 ...

  6. BZOJ 1853 【Scoi2010】 幸运数字

    Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认 为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,8 ...

  7. BZOJ 1026 【SCOI2009】 windy数

    Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B,总共有多少个windy数? I ...

  8. BZOJ 3669 【NOI2014】 魔法森林

    Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...

  9. UOJ#58/BZOJ 3052【WC2013】糖果公园

    好写好调的莫队算法,就算上树了仍然好写好调. 传送门 http://uoj.ac/problem/58 简要做法 将树按照dfs序分块,然后将询问按照(u所在块,v所在块,时间)作为关键字进行排序,依 ...

随机推荐

  1. Floyd求最小环并求不同最小环的个数

    FZU2090 旅行社的烦恼 Time Limit: 2000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u [Subm ...

  2. Linux系统下tomcat安装配置

    Linux系统中Tomcat的安装配置. 前提JDK已经安装好. 安装 下载tomcatwget http://mirrors.cnnic.cn/apache/tomcat/tomcat-8/v8.0 ...

  3. Ubuntu 16.04 安装和配置 Redis

    因为发现之前手动安装的 redis 与现有的教程不一样,所以总结统一一下安装的标准步骤. 安装依赖项 为了获取最新版本的 Redis,我们将从源代码进行编译和安装.下载源代码之前,需要先安装一些编译所 ...

  4. Lucene.net的简单使用

    一.Lucene.net的简单介绍 1.为什么要使用Lucene.net       使用like的模糊查询,模糊度太低,中间添加几个字就无法查找.同时会造成数据库的全文检索,效率低下,数据库服务器造 ...

  5. MVC之Filter

    过滤器的理解 Filter就是过滤器,在WebForm中,各种管道事件就是相当于过滤器,在MVC中,过滤器是单独的一种机制,分为方法过滤器和异常处理过滤器,方法过滤器实现的功能是在执行某一个请求得方法 ...

  6. Servlet + JSP 时代

    Spring,Django,Rails,Express这些框架技术的出现都是为了解决什么问题,现在这些框架都应用在哪些方面? - 知乎 https://www.zhihu.com/question/2 ...

  7. 无题II---hdu2236(二分,匈牙利)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2236 要求最大值与最小值的差值最小,是通过枚举边的下限和上限来完成 只需要用二分找一个区间,然后不断枚 ...

  8. Python开发【笔记】:concurrent.futures 平行运算

    平行运算 前言: 编写Python程序时,我们可能会遭遇性能问题,即使优化了代码,程序也依然有可能运行的很慢,从而无法满足我们对执行速度的要求,目前的计算机,其cpu核心数越来越多,于是,我们可以考虑 ...

  9. Mac OS X 在 Finder 里快速创建文本文件

    Automator 新建一个 Application   选取:应用程序 实用工具→运行AppleScript 添加一个动作 "Run AppleScript"代码如下: on r ...

  10. (5)调度器(scheduler)

    继承关系 原理介绍 Cocos2d-x调度器为游戏提供定时事件和定时调用服务.所有Node对象都知道如何调度和取消调度事件,使用调度器有几个好处: 每当Node不再可见或已从场景中移除时,调度器会停止 ...