BZOJ 2806 cheat
首先这个题目显然是要二分转换成判断可行性的
之后我们考虑DP
设f(i)表示 1->i 熟悉的子串的长度的最大值
那么对于i这个点,要么不在熟悉的子串中,要么在熟悉的子串中
所以得到
f(i)=max(f(i-1),f(j)+i-j);
其中i-j是划分的熟悉的子串的长度,要满足以下条件:
1、i-j>=k (k为二分出来的值)
2、[j+1,i]这段串是给定标准文章库的一个子串
我们又知道若[j+1,i]是一个满足条件的子串,那么[j+2,i]也一定满足条件
假设我们已知最小的p满足[p+1,i]是一个满足条件的子串,定义L=i-p
那么条件2转化为 i-j<=L
求特定区间的最大值,且左右端点是单调的,我们是可以用单调队列的
那么现在问题就是求解最小的p使得[p+1,i]满足条件
即求解给定串S的一个前缀的最长满足条件的后缀,这时可以用后缀自动机做的
每次只需要在上次的基础上顺着parent树向上寻找匹配就可以了
注意:当寻找到SAM上的一个可匹配的节点时,当前的L并不一定是这个合法节点的len值+1
因为SAM上的节点的len值为其可以取得的长度的最大值,它有可能比上一次的L要大
所以我的代码对这种情况进行了一下处理QAQ
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std; const int maxn=1100010;
int n,m,cnt,la,len;
char s[maxn];
struct Node{
int next[3];//0 1 2
int len,link;
}st[maxn<<1];
int Q[maxn],h,t;
int f[maxn]; void init(){
cnt=la=0;
st[0].link=-1;
}
void add(int c){
int cur=++cnt;
st[cur].len=st[la].len+1;
int p;
for(p=la;p!=-1&&st[p].next[c]==0;p=st[p].link)st[p].next[c]=cur;
if(p==-1)st[cur].link=0;
else{
int q=st[p].next[c];
if(st[q].len==st[p].len+1)st[cur].link=q;
else{
int clone=++cnt;
st[clone]=st[q];
st[clone].len=st[p].len+1;
for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=clone;
st[q].link=st[cur].link=clone;
}
}la=cur;
}
bool check(int k){
h=1;t=0;f[0]=0;
int p=0,L=0;
for(int i=1;i<=len;++i){
if(i>=k){
while(h<=t&&f[Q[t]]-Q[t]<f[i-k]-(i-k))t--;
Q[++t]=i-k;
}
int now=s[i]-'0';
int cur=p;
for(;p!=-1&&st[p].next[now]==0;p=st[p].link);
f[i]=f[i-1];
if(p==-1){p=0;L=0;continue;}
if(p==cur)L++;
else L=st[p].len+1;
p=st[p].next[now];
while(h<=t&&i-Q[h]>L)h++;
if(h<=t)f[i]=max(f[i],f[Q[h]]-Q[h]+i);
}return len*9<=f[len]*10;
} int main(){
scanf("%d%d",&n,&m);init();
for(int i=1;i<=m;++i){
scanf("%s",s+1);len=strlen(s+1);
for(int j=1;j<=len;++j)add(s[j]-'0');
add(2);
}
while(n--){
scanf("%s",s+1);len=strlen(s+1);
int L=0,R=len;
while(L<R){
int mid=L+((R-L+1)>>1);
if(check(mid))L=mid;
else R=mid-1;
}printf("%d\n",L);
}return 0;
}
BZOJ 2806 cheat的更多相关文章
- [CTSC 2012][BZOJ 2806]Cheat
真是一道好题喵~ 果然自动机什么的就是要和 dp 搞基才是王道有木有! A:连 CTSC 都叫我们搞基,果然身为一个程序猿,加入 FFF 团是我此生最明智的选择.妹子什么闪边去,大家一起来搞基吧! Q ...
- 后缀自动机SAM BZOJ 2806
终于遇到了一道后缀数组不能过 一定要学SAM的题... (看了半个下午+半个上午) 现在总结一下(是给我自己总结..所以只总结了我觉得重要的 .. 看不太懂的话可以To http://blog.c ...
- bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 583 Solved: 330[Submit][Statu ...
- BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]
2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...
- 【BZOJ 2806】 2806: [Ctsc2012]Cheat (SAM+二分+DP+单调队列)
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1262 Solved: 643 Description ...
- 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
传送门 好久没刷bzoj惹…… 题意不说可以嘛. 首先二分答案. SAM的事情搞完以后就是dp辣. 我们已经对于每个位置i,找到了最小的一个k,使得[k,i]这个子串在模版串中出现过.那么我们需要做的 ...
- bzoj 2806 [Ctsc2012]Cheat——广义后缀自动机+单调队列优化DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2806 只想着怎么用后缀数据结构做,其实应该考虑结合其他算法. 可以二分那个长度 L .设当前 ...
- BZOJ 2806 【CTSC2012】 Cheat
题目链接:Cheat 话说这道题很久以前某人就给我们考过,直到现在,我终于把这个坑填上了…… 这道题要我们把一个串\(S\)划分成若干块,每块长度不小于\(L_0\),使得能够在文章库中完全匹配的块的 ...
随机推荐
- javascript笔记——placehold
<input type="text" name="搜索" value="搜索" placeholder="搜索" ...
- 《Web编程入门经典》
在我还不知道网页的基础结构的时候,我找过很多本介绍Web基础的书籍,其中这本<Web编程入门经典>,我认为是最好的. 这本书内容很全面.逻辑很严谨.结构很清晰.语言文字浅显易懂. 看这本书 ...
- c# Aes加解密和对象序列化
aes加解密 public class AesCryptto { private string key = "hjyf57468jhmuist"; private string i ...
- Kail安装Parallels tools
今天在安装虚拟机里面安装kail,在安装虚拟机提供的tools时候提示没有权限,如图: 后面经过自己证实首先tools是挂载的cdrom,在这样挂载下是没有写权限的(类似于windows下面读取光盘光 ...
- JavaScript 防止事件冒泡
在我们书写一个弹窗的时候,我们往往需要点击弹窗的其他地方来隐藏弹窗. 通常我们会写成: $(document).bind('click',function(){ $('.pop-box').hide( ...
- 基于Golang的游戏服务器框架cellnet开发日记(二)
看官们肯定还有大部分不是很熟悉Actor模型. 我这里基于Erlang, Skynet等语言和框架库来实战型解释下Actor模型. Actor概念 Actor模型和OO类似, 都是符合人的思维模式进 ...
- php验证码的简单例子
php随机验证码: <?php $image_width=140; $image_height=50; srand(microtime()*10000); ...
- J2EE中文乱码处理
在JAVA WEB开发的过程中,经常会遇到中文乱码的情况,中文乱码主要是在浏览器与服务器交互传递数据的时候发生的.对于这个棘手的问题,我参考(韩顺平老师)视频将处理方法总结与此,供自己以及大家开发的时 ...
- 特定用户QQ群聊天记录导出的实现
一.把QQ群的聊天记录txt格式导出 消息管理器 -> 选择要导出的群 -> 右击.导出 这里要注意 : 导出之后的 文本是 unicode 编码的,需要转换 ==|| 之前不知道,搞 ...
- android如何切换皮肤
1.先定义attr文件 <?xml version="1.0" encoding="utf-8"?> <resources> <a ...