bzoj2806
广义后缀自动机+二分+单调队列+dp
这道题其实就是一个简单dp,dp[i]表示匹配到i最长匹配多少,设val[i]表示当前位置和原串的最长公共长度,二分的长度是L,那么要求dp[i]=max(dp[i-1],dp[j]+i-j)要求L<=i-j<=val[i],那么也就是j>=i-val[i],前面的l每次把不符合的L>i-j弹掉,由于val[i]每次最多增加1,所以i-val[i]是不增的,所以可以用单调队列维护。最先开始我还想怎么在自动机上dp,结果直接求出val就行了。
#include<bits/stdc++.h>
using namespace std;
const int N = 2.2e6 + ;
int n, m;
int q[N], dp[N], val[N];
char s[N];
namespace SAM
{
struct node {
int val, par;
int ch[];
} t[N];
int last = , sz = , root = ;
int nw(int _)
{
t[++sz].val = _;
return sz;
}
void extend(int c)
{
int p = last, np = nw(t[p].val + );
while(p && !t[p].ch[c]) t[p].ch[c] = np, p = t[p].par;
if(!p) t[np].par = root;
else
{
int q = t[p].ch[c];
if(t[q].val == t[p].val + ) t[np].par = q;
else
{
int nq = nw(t[p].val + );
memcpy(t[nq].ch, t[q].ch, sizeof(t[q].ch));
t[nq].par = t[q].par;
t[q].par = t[np].par = nq;
while(p && t[p].ch[c] == q) t[p].ch[c] = nq, p = t[p].par;
}
}
last = np;
}
} using namespace SAM;
bool check(int L, int n)
{
int l = , r = , ans = ;
for(int i = ; i <= n; ++i)
{
dp[i] = dp[i - ];
if(i < L) continue;
while(l <= r && dp[i - L] + L > dp[q[r]] + (i - q[r])) --r;
q[++r] = i - L;
while(l <= r && i - q[l] > val[i]) ++l;
if(l > r || i - q[l] < L || i - q[l] > val[i]) continue;
dp[i] = max(dp[i - ], dp[q[l]] + (i - q[l]));
}
return dp[n] * >= * n;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= m; ++i)
{
last = root;
scanf("%s", s + );
int len = strlen(s + );
for(int j = ; j <= len; ++j) extend(s[j] - '');
}
for(int i = ; i <= n; ++i)
{
scanf("%s", s + );
int len = strlen(s + ), u = root, step = ;
for(int j = ; j <= len; ++j)
{
if(t[u].ch[s[j] - '']) u = t[u].ch[s[j] - ''], ++step;
else
{
while(u && !t[u].ch[s[j] - '']) u = t[u].par;
if(!u) u = root, step = ;
else
{
step = t[u].val + ;
u = t[u].ch[s[j] - ''];
}
}
val[j] = step;
}
int l = , r = len + , ans = ;
while(r - l > )
{
int mid = (l + r) >> ;
if(check(mid, len)) l = ans = mid;
else r = mid;
}
printf("%d\n", ans);
}
return ;
}
bzoj2806的更多相关文章
- 【bzoj2806】 Ctsc2012—Cheat
http://www.lydsy.com/JudgeOnline/problem.php?id=2806 (题目链接) 题意 给出M个字符串组成“标准库”.定义L表示将一个字符串分成若干段,每一段的长 ...
- 【BZOJ2806】Cheat(后缀自动机,二分答案,动态规划,单调队列)
[BZOJ2806]Cheat(后缀自动机,二分答案,动态规划,单调队列) 题面 BZOJ 洛谷 题解 很有趣的一道题啊 对于在所有的串上面进行匹配? 很明显的后缀自动机 所以先构建出广义后缀自动机 ...
- 【BZOJ2806】[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化DP
[BZOJ2806][Ctsc2012]Cheat Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数接下来M行的01串,表示标准作文库接下来N行的 ...
- bzoj2806 [Ctsc2012]Cheat
我们的目的就是找到一个最大的L0,使得该串的90%可以被分成若干长度>L0的字典串中的子串. 明显可以二分答案,对于二分的每个mid 我们考虑dp:f[i]表示前i个字符,最多能匹配上多少个字符 ...
- BZOJ2806:[CTSC2012]Cheat(广义SAM,二分,DP)
Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 Output N行,每行一 ...
- 【BZOJ2806】Cheat 【广义后缀自动机+单调队列优化dp+二分】
题意 有M篇标准作文组成了一个作文库(每篇作文都是一个01的字符串),然后给出N篇作文(自然也是01字符串).如果一个长度不小于L的串在作文库中出现过,那么它是熟悉的.对于某一篇作文,我们要把它分为若 ...
- [BZOJ2806][CTSC2012]熟悉的文章(Cheat)
bzoj luogu 题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么 ...
- BZOJ2806 [Ctsc2012]Cheat 【后缀自动机 + 二分 + 单调队列优化DP】
题目 输入格式 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库 的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 输出格式 N行,每行一个整数,表示这篇作文的 ...
- bzoj2806 [Apio2012]dispatching【可并堆】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2809 保存可并堆模版代码. #include <cstdio> #include ...
随机推荐
- 分布式数据库数据从属与client与server的数据同步
老实说,眼下市面上很多产品,的确是不成熟的产品. 用过一些,给人蛋痛的感觉. 导言 分布还是集总 今天我们来探讨一个非常重要的问题. 每一个程序猿都有其思想,我的思想之中的一个,就是分布式. 分布式, ...
- 【Bootstrap】一个兼容IE8、谷歌等主流浏览器的受众门户式风格页面
上一次写的<[Bootstrap]一个兼容IE8.谷歌等主流浏览器的受众巨幕式风格页面>(点击打开链接) 部分老一辈的需求可能对这样的后现代的风格并不惬意, 没关系,我们全然能够改变布局 ...
- Unity光滑与粗糙的材质——相似于生锈的金属表面
纹理是在Photoshop中制作的,终于效果则是在Unity里得到的.这样的类型的材质.在3D游戏中非经常见.
- vs学习过程中遇见的各种问题
1. argument to type "char *"is incompatible with parameter of type "LPWSTR" 解决: ...
- Fakeapp2.2安装,使用简记
1,硬件和操作系统,支持cuda的Nvidia显卡,8G及以上的内存,Windows10 x64(推荐,Windows7 x64亲测可行),可以使用gpu-z查看你的显卡详情 我的笔记本是双显卡(都是 ...
- 如何将mysql的路径加入环境变量
1.打开终端,输入: cd ~ 会进入~文件夹 2.然后输入:touch .bash_profile 回车执行后, 2.再输入:open -e .bash_profile 会在TextEdit中打开这 ...
- 远程访问Linux的常见方式
访问方式 不加密文字界面:telnet.rsh 加密文字界面:SSH 图形界面:Xdmcp.RDP.VNC SSH SSH用来取代finger.R shell(rlogin.rcp.rsh).teln ...
- RequestDispatcher用法
1.具体用法: RequestDispatcher dispatcher = req.getRequestDispatcher("updateByUserId_001.jsp"); ...
- css定位的元素内层不自动扩高解决
给最外层的CSS加上一行: 1 position: relative; /* 给最外层加上这行 */
- Oracle Meger into 函数
Oracle 在 9i 引入了 merge 命令, 通过这个 merge 能够在一个SQL 语句中对一个表同时执行 inserts 和 updates 操作.Merge into 可以实现用 B 表来 ...