BZOJ 2806 [Ctsc2012]Cheat ——后缀自动机 单调队列优化DP
先建出广义后缀自动机。
然后跑出文章中每一个位置的最大匹配距离。
然后定义$f[i]$表示匹配到以$i$结尾的串时,最长的匹配距离。
显然可以二分$L$的取值。
然后容易得到$DP$方程
$f[i]=max(f[i-1],f[j]+i-j)(j<=i-L)$
然后就发现$j$属于一个区间,然后就可以单调队列优化了。
#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define maxn 2200005 namespace SAM{
int last,cnt,go[maxn][2],l[maxn],fa[maxn],n,m,q;
int f[maxn],que[maxn],hd,tl,d[maxn];
char s[maxn];
void init(){last=cnt=1;}
void add(int x)
{
int q,p=last;
if (q=go[p][x])
{
if (l[q]==l[p]+1) last=q;
else
{
int nq=last=++cnt;
l[nq]=l[p]+1;
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q];fa[q]=nq;
for (;go[p][x]==q&&p;p=fa[p]) go[p][x]=nq;
last=nq;
}
}
else
{
int np=last=++cnt; l[np]=l[p]+1;
for (;p&&!go[p][x];p=fa[p]) go[p][x]=np;
if (!p) fa[np]=1;
else
{
q=go[p][x];
if (l[q]==l[p]+1) fa[np]=q;
else
{
int nq=++cnt;l[nq]=l[p]+1;
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq;
}
}
}
}
void ins()
{
last=1;
scanf("%s",s+1); n=strlen(s+1);
F(i,1,n) add(s[i]-'0');
}
bool check(int mid)
{
f[0]=0; tl=0;hd=1;
F(i,1,n)
{
f[i]=f[i-1];int p=i-mid;
if (p>=0)
{
while (hd<=tl&&f[que[tl]]-que[tl]<f[i-mid]-p)tl--;
que[++tl]=p;
}
while (hd<=tl&&que[hd]<i-d[i]) hd++;
if (hd<=tl) f[i]=max(f[i],f[que[hd]]+i-que[hd]);
}
if (f[n]*10>=n*9) return true;
else return false;
}
void dp()
{
scanf("%s",s+1); n=strlen(s+1);
memset(d,0,(n+1)*sizeof(int));
int now=1,t=0;
F(i,1,n)
{
if (go[now][s[i]-'0'])
now=go[now][s[i]-'0'],t++;
else
{
while (now&&!go[now][s[i]-'0']) now=fa[now];
if (!now) now=1,t=0;
else t=l[now]+1,now=go[now][s[i]-'0'];
}
d[i]=t;
}
int l=0,r=n;
while (l<r)
{
int mid=(l+r)/2+1;
if (check(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
}
void solve()
{
init();
scanf("%d%d",&q,&m);
F(i,1,m) ins();
F(i,1,q) dp();
}
} int main()
{
using namespace SAM;
solve();
}
BZOJ 2806 [Ctsc2012]Cheat ——后缀自动机 单调队列优化DP的更多相关文章
- BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]
2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...
- bzoj 2806 [Ctsc2012]Cheat——广义后缀自动机+单调队列优化DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2806 只想着怎么用后缀数据结构做,其实应该考虑结合其他算法. 可以二分那个长度 L .设当前 ...
- BZOJ 2806 [Ctsc2012]Cheat (后缀自动机+二分+单调队列+dp)
题目大意: 给你一堆模式串和文本串 对于每个文本串,我们可以把它不可重叠地拆分成很多子串,如果拆分出的串作为子串出现在了任何一个模式串中,我们称它是“眼熟的”,我们必须保证“眼熟的”子串总长度不小于文 ...
- bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 583 Solved: 330[Submit][Statu ...
- 【BZOJ2806】【CTSC2012】Cheat - 广义后缀自动机+单调队列优化DP
题意: Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 Output N行 ...
- 【BZOJ2806】Cheat 【广义后缀自动机+单调队列优化dp+二分】
题意 有M篇标准作文组成了一个作文库(每篇作文都是一个01的字符串),然后给出N篇作文(自然也是01字符串).如果一个长度不小于L的串在作文库中出现过,那么它是熟悉的.对于某一篇作文,我们要把它分为若 ...
- BZOJ 1010: [HNOI2008]玩具装箱toy | 单调队列优化DP
原题: http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题解: #include<cstdio> #include<algo ...
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...
- bzoj 1499 [NOI2005]瑰丽华尔兹——单调队列优化dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1499 简单的单调队列优化dp.(然而当时却WA得不行.今天总算填了坑) 注意滚动数组赋初值应 ...
随机推荐
- HDU 5092 Seam Carving (dp)
题意,给一个数字矩阵,要求从上往下的一条路径,使这条路径上数字之和最小,如有多条输出最靠右的一条. 数字三角形打印路径... 一般打印路径有两种选择,一是转移的时候加以记录,二是通过检查dp值回溯. ...
- 【Python全栈-JavaScript】JavaScript-字符串详解
JavaScript-字符串详解 预热:Number() 方法 <script> //重要等级 1,2,3,4,5 var s=10; //最高级别5 var s1=new Number( ...
- Bootstrap历练实例:默认的列表组
Bootstrap 列表组 本章我们将讲解列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-grou ...
- cocos2dx通过ndk编译c++库
ndk编译c++库,然后通过jni调用实现重要代码封装,是安卓应用中最常用的技术,一方面可以将重要的代码实现隐藏,防止泄漏,也可以提高打包速度. ndk里面的sample文件夹中有很多实用的例子,其中 ...
- iOS开发之WIFI,3G/4G两种网络同时使用技巧
最近遇到一个比较奇葩的需求:App与硬件通过WiFi LAN通信, 同时App需要与服务器通过3G/4G WAN通信,如下图: 众所周知,手机同时打开WiFi和3G时候,会优先走WiFi.这个该如何实 ...
- Vue路由跳转到新页面时 默认在页面最底部 而不是最顶部 的解决
今天碰到一个问题 vue路由跳转到新的页面时会直接显示页面最底部 正常情况下是显示的最顶部的 而且好多路由中不是全部都是这种情况 折腾好长时间也没解决 最后在网上找到了解决办法 其实原理很 ...
- [转载] bp神经网络推导
https://blog.csdn.net/fanxin_i/article/details/80212906 看了这么多就这个推的清楚,转嘞
- 【Python学习之五】高级特性2(切片、迭代、列表生成器、生成器、迭代器)
2.迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration).在Python中,迭代是通过for ... in来完成的. ...
- paper:synthesizable finite state machine design techniques using the new systemverilog 3.0 enhancements 之 FSM Coding Goals
1.the fsm coding style should be easily modifiable to change state encoding and FSM styles. FSM 的的 状 ...
- html5音频audio对象处理以及ios微信端自动播放和息屏后唤醒的判断---可供参考(功能都完整实现了,只是细节还没处理的很好)
// html模版中的 此处结合了weui样式整合的微信手机端片段代码(不可直接粘贴复制进行使用)里面含有一些php的写法,可直接略过..###重点参考js代码### <div> < ...