[CTSC2012]熟悉的文章 (后缀自动机 单调队列)
/*
首先答案显然是具有单调性的, 所以可以二分进行判断
然后当我们二分过后考虑dp来求最长匹配个数, 发现每个点能够转移的地点 肯定是一段区间, 然后这样就能够得到一个log^2算法
至于每个点的匹配最长区间, 我们可以预处理出所有地点的最长匹配串
然后发现这个东西可以进行单调栈优化, 原因是往后能往前最大匹配到的点是不会超过前面的, 否则前面那个也会更长
然后就能快乐地一个log了
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define ll long long
#define M 2800010
#define mmp make_pair
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
char s[M];
int ch[M][2], cnt = 1, lst = 1, fa[M], len[M], n, m;
void insert(int c) {
int p = ++cnt, f = lst;
lst = p;
len[p] = len[f] + 1;
while(f && !ch[f][c]) ch[f][c] = p, f = fa[f];
if(f == 0) {
fa[p] = 1;
} else {
int q = ch[f][c];
if(len[q] == len[f] + 1) {
fa[p] = q;
} else {
int nq = ++cnt;
memcpy(ch[nq], ch[q], sizeof(ch[q]));
fa[nq] = fa[q];
len[nq] = len[f] + 1;
fa[p] = fa[q] = nq;
while(f && ch[f][c] == q) ch[f][c] = nq, f = fa[f];
}
}
}
int q[M], h, t, pre[M], f[M];
bool check(int k) {
int l = strlen(s + 1);
h = 1, t = 0;
for(int i = 1; i <= l; i++) {
f[i] = f[i - 1];
if(i < k) continue;
while(h <= t && f[q[t]] - q[t] <= f[i - k] - i + k) t--;
q[++t] = i - k;
while(h <= t && q[h] < i - pre[i]) h++;
if(h <= t) f[i] = max(f[i], f[q[h]] + i - q[h]);
}
return f[l] * 10 >= l * 9;
}
void getpre() {
int up = strlen(s + 1), now = 1, lenn = 0;
for(int i = 1; i <= up; i++) {
int c = s[i] - '0';
while(now && !ch[now][c]) now = fa[now], lenn = len[now];
if(!now) now = 1, lenn = 0;
else now = ch[now][c], lenn++;
pre[i] = lenn;
}
}
int work() {
getpre();
int l = 1, r = strlen(s + 1);
while(l + 1 < r) {
int mid = (l + r) >> 1;
if(check(mid)) l = mid;
else r = mid;
}
if(!check(l)) return -1;
if(check(r)) return r;
return l;
}
int main() {
n = read(), m = read();
for(int i = 1; i <= m; i++) {
lst = 1;
scanf("%s", s + 1);
int l = strlen(s + 1);
for(int j = 1; j <= l; j++) insert(s[j] - '0');
}
while(n--) {
scanf("%s", s + 1);
cout << work() << "\n";
}
return 0;
}
[CTSC2012]熟悉的文章 (后缀自动机 单调队列)的更多相关文章
- [CTSC2012]熟悉的文章(后缀自动机+动态规划)
题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么觉得熟悉,仿佛是某些范 ...
- [CTSC2012]熟悉的文章 后缀自动机
题面:洛谷 题解: 观察到L是可二分的,因此我们二分L,然后就只需要想办法判断这个L是否可行即可. 因为要尽量使L可行,因此我们需要求出对于给定L,这个串最多能匹配上多少字符. 如果我们可以对每个位置 ...
- 【BZOJ2806】【CTSC2012】Cheat - 广义后缀自动机+单调队列优化DP
题意: Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 Output N行 ...
- 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
先建出广义后缀自动机. 然后跑出文章中每一个位置的最大匹配距离. 然后定义$f[i]$表示匹配到以$i$结尾的串时,最长的匹配距离. 显然可以二分$L$的取值. 然后容易得到$DP$方程 $f[i]= ...
- 【BZOJ2806】Cheat 【广义后缀自动机+单调队列优化dp+二分】
题意 有M篇标准作文组成了一个作文库(每篇作文都是一个01的字符串),然后给出N篇作文(自然也是01字符串).如果一个长度不小于L的串在作文库中出现过,那么它是熟悉的.对于某一篇作文,我们要把它分为若 ...
- P4022 [CTSC2012]熟悉的文章
题目 P4022 [CTSC2012]熟悉的文章 题目大意:多个文本串,多个匹配串,我们求\(L\),\(L\)指(匹配串中\(≥L\)长度的子串出现在文本串才为"熟悉",使得匹配 ...
- [CTSC2012]熟悉的文章(广义后缀自动机+二分答案+单调队列优化DP)
我们对作文库建出广义后缀自动机.考虑用\(SAM\)处理出来一个数组\(mx[i]\),表示从作文的第\(i\)个位置向左最远在作文库中出现的子串的长度.这个东西可以在\(SAM\)上跑\(trans ...
随机推荐
- Quest for sane signals in Qt - step 1 (hand coding a Q_OBJECT)
探索qt的信号ref: http://crazyeddiecpp.blogspot.hk/2011/01/quest-for-sane-signals-in-qt-step-1.html If it ...
- AIX系统日志
1.系统错误日志 存放路径:/var/adm/ras/errlog 说明:该日志记录了系统所检测到的软硬件故障和错误,尤其对系统的硬件故障有很大的参考价值,是AIX提供的最有价值的日志之一, errl ...
- js将foo-bar转为fooBar
这是一道js的面试题,就是考察将普通面命转为小驼峰命名 <!DOCTYPE html> <html lang="en"> <head> < ...
- php Call to undefined function imagettftext()问题解决
测试代码出现报错Call to undefined function imagettftext(),发现是gd库出现了问题 通过phpInfo()查看 gd库已经开启,但是里边没有freeType 和 ...
- Linux rm命令详解
Linux rm命令 Linux rm命令用于删除一个文件或者目录 语法: rm [options] name... 参数解释: -f, --force 强制删除.忽略不存在的文件,不提示确认 -i ...
- Spring Cloud(Dalston.SR5)--Eureka 常用配置
配置参数 默认值 说明 服务注册中心配置 Bean类:org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean eu ...
- mysql官方测试 DB
https://dev.mysql.com/doc/employee/en/ http://blog.51cto.com/dnsliu/ http://blog.csdn.net/zengxuewen ...
- apache配置https协议
安装openssl有两种方式,第一种直接下载安装包,装上就可运行:第二种可以自己下载源码,自己编译.下面对两种方式均进行详细描述. 一.下载和安装openss 方法一:直接使用openssl安装包 W ...
- php 直接获取url参数赋值成变量。省去繁琐的获取参数,再一个个赋值
php 直接获取url参数赋值成变量.省去繁琐的获取参数,再一个个赋值 parse_url() 该函数可以解析 URL,返回其组成部分.它的用法如下: array parse_url(string $ ...
- 构建Jenkins自动化编译管理环境
今天研究了一下Jenkins,有了一个粗浅的认识,顺手把构建的过程说一下,后续慢慢补充: (1)Secure CRT 连接到Linux服务器 要注意的一点是,要搞好一个文件传输的路子,否则不好传东西. ...