题目链接: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. Android通知栏的高度获取

    public static int getStatusBarHeight(Context context){ Class<?> c = null; Object obj = null; F ...

  2. ExtJS学习

    ExtJS是一门比较纠结的框架,自己不太熟,因为现在在做一些老项目,所以没办法要学点.记录下.其实Ext也不是很难,主要是多查查API,了解其基本的用法,然后慢慢去学习,学成之后做管理系统还是很有优势 ...

  3. tomcat项目快速启动设置

    1.现象:tomcat启动项目时,耗费10几秒的时间 2.(tomcat7)解决:打开$JAVA_HOME/jre/lib/security/java.security这个文件 找到下面的内容:sec ...

  4. supervisor 配置篇

    1,配置管理进程 进程管理配置参数,不建议全都写在supervisord.conf文件中,应该每个进程写一个配置文件放在include指定的目录下包含进supervisord.conf文件中. 1&g ...

  5. Android官方架构组件指南

    此指南适用于那些曾经或现在进行Android应用的基础开发,并希望了解和学习编写Android程序的最佳实践和架构.通过学习来构建强大的生产级别的应用. 注意:此指南默认你对Android开发有比较深 ...

  6. Oracle等待事件之db file scattered read

    1.产生原因 该等待事件通常发生在数据库多块读时,表示发生了与全表扫描和快速索引扫描相关的等待.通常意味着全表扫描过多,或者I/O 能力不足,或者I/O 竞争. 2.确定产生问题对象方法 a)查找全表 ...

  7. RGBA HSB opengl光照模型

    RGBA HSB   HSV颜色模型对应于画家的配色的方法.画家用改变色浓和色深的方法来从某种纯色获得不同色调的颜色.其做法是:在一种纯色中加入白色以改变色浓,加入黑色以改变色深,同时加入不同比例的白 ...

  8. redis cluster 集群畅谈(一)

    redis单机在大数据量情况的会出现瓶颈问题,通过redis 主从架构和 哨兵集群结合可以实现99.99% 高可用 .水平扩容支持更高QPS的解决方案. 在大数据量面前,主从架构结合哨兵集群的解决方案 ...

  9. C++ new 长度为0的数组

    在C++中可以new一个长度为0的数组,通过下面的语句: char* p = new char[0]; 指针p中保存一个非NULL的地址,但是你不能够对p指向的内存进行写入,因为p的内存长度为0, 该 ...

  10. python 面向对象 公有属性 用在哪里

    公有属性也可以叫做静态字段 如果每个对象都有一个共同的值 , 应该把它设置为公有属性 公有属性使用场景,每个对象中保存相同的东西时,可以使用公有属性 类找公有属性 过程