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\),使得能够在文章库中完全匹配的块的 ...
随机推荐
- Objective-C 【动态类型检测&响应方法】
------------------------------------------- 动态类型检测 代码: #import <Foundation/Foundation.h> @inte ...
- 版本控制工具--GIT 基本命令(1)
一.安装GIT,在官网上下载安装即可(下面模拟环境是window7) 二.基本操作: 1.创建GIT库: ①先使用mkdir命令创建一个空目录,再使用git init将该目录变成GIT库,会在该目录下 ...
- CAF(C++ actor framework)使用随笔(使用类去构建actor和使用的一些思路)
Class-based actorsA class-based actor is a subtype of event_based_actor and must implement the pure ...
- HTML5之缓存
----- 缓存文件 - 使用UTF-8编码- 以Cache Manifest 开头- 三个基本部分 CACHE MANIFESTmenu.htmlmenu.js# login requires ne ...
- mysql查询区分大小写与自定义排序
mysql查询区分大小写: SELECT id,developer FROM products WHERE developer != '' and developer = binary('LYNN') ...
- linux ubuntu 思源黑体安装
下载地址: 全部:700多M https://github.com/adobe-fonts/source-han-sans/releases/tag/1.001R 可选部分Github : http ...
- 获取当前<script>节点
/* get current JavaScript dom object. */ var all_js = document.getElementsByTagName("script&quo ...
- Java.lang.RuntimeException: Unable to instantiate activity ComponentInfo
如果你更新了ADT的新版本,而工程文件中使用了其他的jar包,也可能会出现"java.lang.RuntimeException: Unable to instantiate activit ...
- Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming
Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming 在Spark2.x中,Spark Streaming获得了比较全面的升级,称为St ...
- 用JS给浏览器的关闭按钮添加事件
以下是指在js中实现,而非 <body onunload="close()"> 这种方法! 因为这样是在unload掉body的时候触发,而无论任何浏览器,都会在关闭的 ...