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\),使得能够在文章库中完全匹配的块的 ...
随机推荐
- spring事务到底用于service层还是dao层
Spring事务为业务逻辑进行事务管理,保证业务逻辑上数据的原子性. 事务得根据项目性质来细分:事务可以设置到三个层面(dao层.service层和web层). 第一:web层事务,这一般是针对那些安 ...
- python 自动化之路 day 10 协程、异步IO、队列、缓存
本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 RabbitMQ队列 Redis\Memcached缓存 Paramiko SSH Twsited网络框架 引子 到目 ...
- JVM系列三:JVM参数设置、分析(转载)
不管是YGC还是Full GC,GC过程中都会对导致程序运行中中断,正确的选择不同的GC策略,调整JVM.GC的参数,可以极大的减少由于GC工作,而导致的程序运行中断方面的问题,进而适当的提高Java ...
- mysql的时间函数
from_unixtime()是MySQL里的时间函数 date为需要处理的参数(该参数是Unix 时间戳),可以是字段名,也可以直接是Unix 时间戳字符串 后面的 '%Y%m%d' 主要是将返回值 ...
- Projected Coordinate Systems
Coordinate Systems Projected Coordinate Systems This is an archive of a previous version of the ArcG ...
- DTCMS添加文章,将tags标签的值赋到SEO关键词上,以及将摘要的值赋到SEO描述
将tags标签的值赋到SEO关键词上 admin\article_edit.aspx中 $(function () { 方法中加上 //tags的值赋到SEO关键词上 $("#txtTag ...
- angular的ng-class
项目内想到要替换class时,第一反应是使用angular最为简单粗暴的class改变方式: 在angular中为我们提供了3种方案处理class: 1:scope变量绑定,如上例.(不 ...
- html实现层叠加
<div id="canvasesdiv" style="position:relative; width:400px; height:300px"> ...
- zencart后台增加菜单选项
如果要在程序中使用额外的参数,在后台控制,添加到菜单属性 在后台 SQL脚本 运行如下 SQL语句 INSERT INTO configuration (configuration_title, co ...
- 有关linux日志分析的详细介绍
linux的日志文件可以帮助我们了解系统所处的状态,比如查出哪些用户有登入,及其它安全相关的一些问题. linux下的日志分析. 以下内容,部分参考了:探讨 linux 日志分析 这篇文章. 1.了解 ...