【BZOJ2806】[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化DP
【BZOJ2806】[Ctsc2012]Cheat
Description
Input
第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库
的行数
接下来M行的01串,表示标准作文库
接下来N行的01串,表示N篇作文
Output
N行,每行一个整数,表示这篇作文的Lo 值。
Sample Input
10110
000001110
1011001100
Sample Output
HINT
输入文件不超过1100000字节
注意:题目有改动,可识别的长度不小于90%即可,而不是大于90%
题解:显然答案是可二分的。但是二分之前,我们还需要知道字符串中每个位置往前最多能匹配多少,由于是多个文本串,所以我们要用广义SAM。
这其实是另一道spoj的题(不过我没做),其实做法也不难。我们将目标串在SAM上跑一遍,如果在某个节点失配了,即ch[x][a]=0,那么我们就让x沿着parent指针已知向上跳,直到匹配上为止,然后令sum=mx[x]+1。如果没有失配,则sum++。(注意,ch[x][a]指向的点的mx不一定=mx[x]+1,实际上,那个点的mx=mx[x在parent树上的某个子孙]+1)
然后我们设f[i]表示位置i能往前匹配的最长长度,那么有如下DP方程:
$f[i]=max(f[i-1],f[j]+i-j)|i-sm[i]\le j \le i-L_0$
显然我们用单调队列维护f[j]-j的最大值就行了。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n,m,tot,len;
const int maxn=2200010;
int pre[maxn],ch[maxn][2],mx[maxn],sm[maxn],f[maxn],q[maxn];
char str[maxn];
int extend(int x,int p)
{
int np=++tot;
mx[np]=mx[p]+1;
for(;p&&!ch[p][x];p=pre[p]) ch[p][x]=np;
if(!p) pre[np]=1;
else
{
int q=ch[p][x];
if(mx[q]==mx[p]+1) pre[np]=q;
else
{
int nq=++tot;
pre[nq]=pre[q],pre[np]=pre[q]=nq,mx[nq]=mx[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
for(;p&&ch[p][x]==q;p=pre[p]) ch[p][x]=nq;
}
}
return np;
}
void match()
{
int i,u,a,sum=0;
for(u=i=1;i<=len;i++)
{
a=str[i]-'0';
if(ch[u][a]) sum++,u=ch[u][a];
else
{
for(;u&&!ch[u][a];u=pre[u]);
if(!u) sum=0,u=1;
else sum=mx[u]+1,u=ch[u][a];
}
sm[i]=sum;
}
}
bool solve(int sta)
{
int i,j,h=1,t=0;
for(i=0;i<=len;i++) f[i]=0;
for(i=sta-1;i<=len;i++)
{
while(h<=t&&q[h]<i-sm[i]) h++;
f[i]=f[i-1];
if(sm[i]>=sta) f[i]=max(f[i],f[q[h]]-q[h]+i);
j=i-sta+1;
while(h<=t&&f[q[t]]-q[t]<=f[j]-j) t--;
q[++t]=j;
}
return f[len]*10>=len*9;
}
int main()
{
scanf("%d%d",&n,&m);
int i,j,a,b,l,r,mid;
for(tot=i=1;i<=m;i++)
{
scanf("%s",str),a=strlen(str);
for(b=1,j=0;j<a;j++) b=extend(str[j]-'0',b);
}
for(i=1;i<=n;i++)
{
scanf("%s",str+1),len=strlen(str)-1;
match();
l=1,r=len+1;
while(l<r)
{
mid=l+r>>1;
if(solve(mid)) l=mid+1;
else r=mid;
}
printf("%d\n",l-1);
}
return 0;
}
【BZOJ2806】[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化DP的更多相关文章
- BZOJ2806 [Ctsc2012]Cheat 【后缀自动机 + 二分 + 单调队列优化DP】
题目 输入格式 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库 的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 输出格式 N行,每行一个整数,表示这篇作文的 ...
- BZOJ2806: [Ctsc2012]Cheat(广义后缀自动机,单调队列优化Dp)
Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数接下来M行的01串,表示标准作文库接下来N行的01串,表示N篇作文 Output N行,每行一个整 ...
- [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- 2018.09.26洛谷P3957 跳房子(二分+单调队列优化dp)
传送门 表示去年考普及组的时候失了智,现在看来并不是很难啊. 直接二分答案然后单调队列优化dp检验就行了. 注意入队和出队的条件. 代码: #include<bits/stdc++.h> ...
- BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]
2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...
- BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...
- 【BZOJ2806】【CTSC2012】Cheat 广义后缀自动机+二分+Dp
题目 题目在这里 思路&做法 我们先对标准作文库建广义后缀自动机. 然后对于每一篇阿米巴的作文, 我们首先把放到广义后缀自动机跑一遍, 对于每一个位置, 记录公共子串的长度\((\)即代码和下 ...
- bzoj 2806 [Ctsc2012]Cheat——广义后缀自动机+单调队列优化DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2806 只想着怎么用后缀数据结构做,其实应该考虑结合其他算法. 可以二分那个长度 L .设当前 ...
- BZOJ 2806 [Ctsc2012]Cheat (后缀自动机+二分+单调队列+dp)
题目大意: 给你一堆模式串和文本串 对于每个文本串,我们可以把它不可重叠地拆分成很多子串,如果拆分出的串作为子串出现在了任何一个模式串中,我们称它是“眼熟的”,我们必须保证“眼熟的”子串总长度不小于文 ...
随机推荐
- IE常见BUG总结(持续更新)
ie6~7下display:inline-block无效 解决方案:需要hack触发hasLayout 1 //IE6.7中内联元素(如span)触发layout属性后, 它的行为和标准中的 inli ...
- Java程序猿修炼之道 之 Logging(3/3) - 怎么分析Log
1. 说明 作为一个程序猿我们常常要做一件事情:获取某个Log文件,从当中找出自己想要的信息. 本文总结了我在工作中使用了哪些工具来分析Log文件获取我想要的信息,我近期几年的工作环境都是server ...
- 利用excel去除txt文本中重复项
2017-04-10 1.要去重的文件,点击右键,选择程序. 2.选择excel表格或者wps表格. 3.excel表格去重:选中单元格——数据——筛选——高级筛选——选择不重复记录——确定 wps表 ...
- Nodejs扩展,实现消息弹窗
參考https://github.com/olalonde/node-notify的实现 模块的C++代码 node_gtknotify.cc #include <v8.h> #inclu ...
- JS杂技之无中间变量的值交换方式
从http://www.cnblogs.com/liuyitian/p/4081517.html#3074553看到一种无中间变量的值交换方式,具体如下: var a = 1;var b = 2;a ...
- 【HTML 元素】嵌入另一张HTML文档、通过插件嵌入内容、嵌入数字表现形式
1.嵌入另一张HTML文档 iframe 元素允许在现有的HTML文档中嵌入另一张文档.下面代码展示了iframe元素的用法: <!DOCTYPE html> <html lang= ...
- Centos 通过yum的方式升级内核
在安装某些软件时,可能对我们的系统内核版本有要求. 比如在安装docker要满足一定的条件,对于centos系统,要求必须是64位,并且内核版本是3.10以上. 如果你的centos操作系统内核低于3 ...
- 倍福TwinCAT(贝福Beckhoff)基础教程 松下官方软件开启报错伺服未就绪怎么办
一般是伺服到电机的动力线没接好(请查看动力线接线是否正确) 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku.com/acetaohai123 我的在线 ...
- python 类特殊成员
class Foo: def __init__(self,age): self.age=age print('init') def __call__(self): print('call') def ...
- DBCC MEMORYSTATUS
内存管理器 输出的第一节是内存管理器.此部分将显示 SQL Server 的总内存消耗. Memory Manager KB ------------------------------ ------ ...