【BZOJ 2806】 2806: [Ctsc2012]Cheat (SAM+二分+DP+单调队列)
2806: [Ctsc2012]Cheat
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 1262 Solved: 643Description
Input
第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库
的行数
接下来M行的01串,表示标准作文库
接下来N行的01串,表示N篇作文Output
N行,每行一个整数,表示这篇作文的Lo 值。
Sample Input
1 2
10110
000001110
1011001100Sample Output
4HINT
输入文件不超过1100000字节
注意:题目有改动,可识别的长度不小于90%即可,而不是大于90%
Source
【分析】
显然可以二分。
然后就是判断。
先用SAM找到i最长向左可以匹配的位置l,决策区间就是[i-l,i-lim],思考一下发现这个决策区间是不断向右移动的,就是类似滑动窗口?这个就可以用单调队列了。
即f[i]=max{f[i-1],f[j]+j-i|i-l<=j<=i-lim}
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 2500010 int mymax(int x,int y) {return x>y?x:y;} struct node
{
int son[],pre,step;
}t[Maxn*]; struct sam
{
int tot,last;
void extend(int k)
{
int np=++tot,p=last;
t[np].step=t[p].step+;
while(p&&!t[p].son[k])
{
t[p].son[k]=np;
p=t[p].pre;
}
if(!p) t[np].pre=;
else
{
int q=t[p].son[k];
if(t[q].step==t[p].step+) t[np].pre=q;
else
{
int nq=++tot;
memcpy(t[nq].son,t[q].son,sizeof(t[nq].son));
t[nq].step=t[p].step+;
t[nq].pre=t[q].pre;
t[q].pre=t[np].pre=nq;
while(p&&t[p].son[k]==q)
{
t[p].son[k]=nq;
p=t[p].pre;
}
}
}
last=np;
}
}sam; char s[Maxn]; int q[Maxn*];
int f[Maxn];
bool check(int x,int ll)
{
int l=,r=;
int nw=,sm=;
for(int i=;i<=ll;i++) f[i]=;
q[]=;
for(int i=;i<=ll;i++)
{
f[i]=f[i-];
int ind=s[i]-'';
while(nw&&!t[nw].son[ind]) nw=t[nw].pre,sm=t[nw].step;
if(t[nw].son[ind]) nw=t[nw].son[ind],sm++;
else {nw=;sm=;continue;}
while(i-x>=&&l<=r&&f[i-x]-(i-x)>f[q[r]]-(q[r])) r--;
if(i-x>=) q[++r]=i-x;
while(l<=r&&(q[l]<i-sm||q[l]>i-x)) l++;
if(l<=r) f[i]=mymax(f[i],f[q[l]]+i-q[l]);
}
return f[ll]*>=ll*;
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
sam.tot=sam.last=;
for(int i=;i<=m;i++)
{
scanf("%s",s);
int ll=strlen(s);
for(int j=;j<ll;j++) sam.extend(s[j]-'');
// sam.extend(2);
sam.last=;
}
for(int i=;i<=n;i++)
{
scanf("%s",s+);
int ll=strlen(s+);
int l=,r=ll;
while(l<r)
{
int mid=(l+r+)>>;
if(check(mid,ll)) l=mid;
else r=mid-;
}
printf("%d\n",l);
}
return ;
}
【打的是广义SAM?
2017-04-18 12:55:48
【BZOJ 2806】 2806: [Ctsc2012]Cheat (SAM+二分+DP+单调队列)的更多相关文章
- 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 二分]
2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...
- bzoj 2806 [Ctsc2012]Cheat——广义后缀自动机+单调队列优化DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2806 只想着怎么用后缀数据结构做,其实应该考虑结合其他算法. 可以二分那个长度 L .设当前 ...
- [bzoj2806][Ctsc2012]Cheat(后缀自动机(SAM)+二分答案+单调队列优化dp)
偷懒直接把bzoj的网页内容ctrlcv过来了 2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1943 ...
- BZOJ.4910.[SDOI2017]苹果树(树形依赖背包 DP 单调队列)
BZOJ 洛谷 \(shadowice\)已经把他的思路说的很清楚了,可以先看一下会更好理解? 这篇主要是对\(Claris\)题解的简单说明.与\(shadowice\)的做法还是有差异的(比如并没 ...
- [acmm week12]二分+dp+单调队列
1004 抄作业 Time Limit: 1sec Memory Limit:256MB Description Zfree虽然平时很爱学习,但是他迫于生活所迫(比如设计cpu实 ...
- luogu P3657 (NOIP2017) 跳房子(二分+DP+单调队列)
题面 传送门 分析 显然答案有单调性,可以二分答案,设当前二分值为g,根据题意我们可以求出跳跃长度的范围[l,r] 考虑DP 子状态: dp[i]表示跳到第i个点时的最大和 状态转移方程 \(dp[i ...
- [NOIP2017普及组]跳房子(二分,单调队列优化dp)
[NOIP2017普及组]跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 nn 个格子, ...
- [BZOJ 2500]幸福的道路 树形dp+单调队列+二分答案
考试的时候打了个树链剖分,而且还审错题了,以为是每天找所有点的最长路,原来是每天起点的树上最长路径再搞事情.. 先用dfs处理出来每个节点以他为根的子树的最长链和次长链.(后面会用到) 然后用类似dp ...
随机推荐
- Isomorphic JavaScript: The Future of Web Apps(译)
Isomorp ...
- LintCode 508: Wiggle Sort
LintCode 508: Wiggle Sort 题目描述 给你一个没有排序的数组,请将原数组就地重新排列满足如下性质 nums[0] <= nums[1] >= nums[2] < ...
- JavaScript设置粘贴板
设置复制 document.body.oncopy = function(){ alert('不许复制'); return false; }; 设置粘贴 document.getElementById ...
- jquery实现简单轮播
先上简单的html代码 <!DOCTYPE HTML> <html> <head> <link rel="stylesheet" type ...
- windows下面安装Python和pip教程
第一步,先来安装Python.windows下面的Python安装一般是通过软件安装包安装而不是命令行,所以首先要在Python的官方主页上面下载最新的Python安装包.下载地址是:https:// ...
- CSS 中 nth-child 和 nth-of-type 的区别
假设有如下代码结构,想要查找 Piggy 那个 p <section> <h1>Words</h1> <p>Little</p> <p ...
- docker 镜像导入和导出
使用 docker commit 即可把这个容器变为一个镜像 docker commit 8d93082a9ce1 ubuntu:myubuntu 这时候 docker 容器会被创建为一个新的 Ubu ...
- AngularJs 文件上传(实现Multipart/form-data 文件的上传)
<!-- 上传yml文件 --> <div class="blackBoard" ng-show="vm.showUpop==true"> ...
- /proc/sys 子目录的作用
该子目录的作用是报告各种不同的内核参数,并让您能交互地更改其中的某些.与 /proc 中所有其他文件不同,该目录中的某些文件可以写入,不过这仅针对 root. 其中的目录以及文件的详细列表将占据过多的 ...
- What does “=>” mean in import in scala?(转自StackOverflow问答)
As others have mentioned, it's an import rename. There is however one further feature that proves ...