BZOJ2806:[CTSC2012]Cheat(广义SAM,二分,DP)
Description
.jpg)
.jpg)
Input
第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数
接下来M行的01串,表示标准作文库
接下来N行的01串,表示N篇作文
Output
N行,每行一个整数,表示这篇作文的L0值。
Sample Input
10110
000001110
1011001100
Sample Output
HINT
输入文件不超过1100000字节
注意:题目有改动,可识别的长度不小于90%即可,而不是大于90%
Solution
首先把广义$SAM$建出来,然后考虑对于一个询问,
我们可以把这个作文放到$SAM$上跑,就可以求得这个字符串的每个位置向前延伸仍然可以匹配的最大长度,记为$Len[i]$。
因为直接求答案不好求,所以我们二分一个答案$lim$
剩下的就是$DP$了。$f[i]$表示到第$i$个位置最多能匹配多少,转移显然。
$f[i]=max(f[i-1]),\sum_{j=lim}^{len} f[i-j]+j$。 单调队列优化一下即可。
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#define N (2200009)
using namespace std; int n,m,len,Len[N],f[N],q[N];
char s[N]; struct SAM
{
int son[N][],fa[N],step[N];
int p,q,np,nq,last,cnt;
SAM(){last=cnt=;} void Insert(int x)
{
p=last; np=last=++cnt; step[np]=step[p]+;
while (p && !son[p][x]) son[p][x]=np,p=fa[p];
if (!p) fa[np]=;
else
{
q=son[p][x];
if (step[q]==step[p]+) fa[np]=q;
else
{
nq=++cnt; step[nq]=step[p]+;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
while (son[p][x]==q) son[p][x]=nq,p=fa[p];
}
}
}
void Find(char s[])
{
int now=,len=;
for (int i=,l=strlen(s); i<l; ++i)
{
int c=s[i]-'';
if (son[now][c]) ++len,now=son[now][c];
else
{
while (now && !son[now][c]) now=fa[now];
if (!now) len=,now=;
else len=step[now]+,now=son[now][c];
}
Len[i+]=len;
}
}
}SAM; bool check(int lim)
{
int head=,tail=,len=strlen(s);
for (int i=; i<=len; ++i)
{
f[i]=f[i-];
if (i-lim<) continue;
while (head<=tail && f[q[tail]]-q[tail]<=f[i-lim]-i+lim) --tail;
q[++tail]=i-lim;
while (head<=tail && q[head]<i-Len[i]) ++head;
if (head<=tail) f[i]=max(f[i],f[q[head]]+i-q[head]);
}
return f[len]*>=len*;
} int main()
{
scanf("%d%d",&n,&m);
for (int i=; i<=m; ++i,SAM.last=)
{
scanf("%s",s);
for (int j=,l=strlen(s); j<l; ++j)
SAM.Insert(s[j]-'');
}
for (int i=; i<=n; ++i)
{
scanf("%s",s);
SAM.Find(s);
int l=,r=strlen(s),ans=;
while (l<=r)
{
int mid=(l+r)>>;
if (check(mid)) ans=mid,l=mid+;
else r=mid-;
}
printf("%d\n",ans);
}
}
BZOJ2806:[CTSC2012]Cheat(广义SAM,二分,DP)的更多相关文章
- 【BZOJ 2806】 2806: [Ctsc2012]Cheat (SAM+二分+DP+单调队列)
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1262 Solved: 643 Description ...
- bzoj 2806: [Ctsc2012]Cheat【广义SAM+二分+dp+单调队列】
把模板串建一个广义SAM 然后在线查询,每次在SAM上预处理出一个a[i]表示i位置向前最多能匹配多长的模板串 二分答案L,dp判断,设f[i]为·~i有几个匹配,转移显然是f[i]=max{f[i- ...
- BZOJ.2806.[CTSC2012]Cheat(广义后缀自动机 DP 单调队列)
题目链接 首先二分答案L.然后就是判断能否将原串划分出一些长度不小于L的子串,这些子串要是给定n个串中的某个串的子串,且满足它们的长度之和不小于原串长度的90%. 贪心多长选一段什么的显然不对.老老实 ...
- 【BZOJ2806】[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化DP
[BZOJ2806][Ctsc2012]Cheat Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数接下来M行的01串,表示标准作文库接下来N行的 ...
- [bzoj2806][Ctsc2012]Cheat(后缀自动机(SAM)+二分答案+单调队列优化dp)
偷懒直接把bzoj的网页内容ctrlcv过来了 2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1943 ...
- BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]
2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...
- bzoj2806: [Ctsc2012]Cheat(SAM+DP)
2806: [Ctsc2012]Cheat 题目:传送门 题解: 感觉这题考的更多的就是DP啊... 看完题目的第一反应就是广义SAM...(然而并不会) 再YY一会儿想起来可以直接将作文库连成一个母 ...
- BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...
- BZOJ 2806 [Ctsc2012]Cheat (后缀自动机+二分+单调队列+dp)
题目大意: 给你一堆模式串和文本串 对于每个文本串,我们可以把它不可重叠地拆分成很多子串,如果拆分出的串作为子串出现在了任何一个模式串中,我们称它是“眼熟的”,我们必须保证“眼熟的”子串总长度不小于文 ...
随机推荐
- Java数据类型和不同数据类型在JVM内存分配
1.java数据类型分类 Java语言是强类型(Strongly typed)语言,强类型包含两方面的含义:①所有的变量必须先声明,后使用:②指定类型的变量只能接受类型与之匹配的值.这意味着每个变量和 ...
- Spark of work
Today I attended a meeting of reviewing code, and I learned a lot from it. In the discuss, we found ...
- 莫名其妙的标记之@noescape
Swift 中经常遇到一些不熟悉的关键字, 例如@autoclosure, @noescape...等等, 为什么要加这样的关键字, 我自己写方法的时候什么时候要加, 什么时候不加, 都是应该考虑的问 ...
- 使用vue+webpack打包时,去掉资源前缀
在build文件夹下找到webpack.prod.conf.js文件,搜索 filename: utils.assetsPath('css/[name].[contenthash].css'), 将[ ...
- display none隐藏后如果表单有数值,那么他的数值还存在!
以前以为display:none后他的值就不存在了, display:none隐藏后如果表单有数值,那么他的数值还存在.(项目出了问题!!) <!DOCTYPE html PUBLIC &quo ...
- CentOS7系列--3.1CentOS7中配置NFS服务
CentOS7配置NFS服务 1. 配置NFS服务器端 1.1. 安装nfs-utils软件 [root@server1 ~]# yum install -y nfs-utils Loaded plu ...
- FineReport中JS如何自定义按钮导出
FineReport支持多种不同的导出方式,直接使用FineReport内置导出按钮可以非常快捷方便的来对各种格式的输出,但是我们在web页面集成中的时候,往往只想将报表内容嵌入到iframe中,而工 ...
- 拖拽进度条(SeekBar)
拖拽进度条(SeekBar) 监听方法:setOnSeekBarChangeListener 监听器:SeekBar.OnSeekBarChangeListener 简单,直接上代码: 1.Activ ...
- 10个经典的Android开源应用项目
Android开发又 将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用.其中也有许许多多的开发者提供了应用开源项目,贡献出他们的智慧和 创造力.学习开源代码是掌握技术的 ...
- 润乾V5手机报表说明文档
1.手机报表实例页面简要说明 index.jsp 是报表资源列表页面: mbReport.jsp 是报表展现页面: mbParam.jsp是参数报表展现页面: echarts.jsp是带有echart ...