题目

题目在这里

思路&做法

我们先对标准作文库建广义后缀自动机。

然后对于每一篇阿米巴的作文, 我们首先把放到广义后缀自动机跑一遍, 对于每一个位置, 记录公共子串的长度\((\)即代码和下文中的\(val\)数组\()\)

接着我们二分答案, 用DP检验。

Dp方程很好想, \(d_i = max \{ d_j + i - j \ | \ i-val_i <= j <= i-lim \}\)

可以用单点队列优化。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib> using namespace std; const int N = 1300010; //数组不能太大, 会T的 int n, m; int val[N]; struct Suffix_Automaton
{ int nxt[N][2], fail[N], sz;
int len[N];
int root; Suffix_Automaton() { } inline int newnode(int l)
{ memset(nxt[sz], 0, sizeof(nxt[sz]));
fail[sz] = 0;
len[sz] = l;
return sz++;
} void init()
{ sz = 1;
root = newnode(0);
} inline int idx(char x) { return x - '0'; } int add(int last, char x)
{ int c = idx(x);
if (nxt[last][c])
{ int p = last, q = nxt[last][c];
if (len[q] == len[p] + 1)
return q;
else
{ int u = newnode(len[p] + 1);
for (int i = 0; i < 2; i++) nxt[u][i] = nxt[q][i];
fail[u] = fail[q];
fail[q] = u;
while (p && nxt[p][c] == q)
{ nxt[p][c] = u;
p = fail[p];
}
return u;
}
}
else
{ int now = newnode(len[last] + 1);
int p = last;
while (p && !nxt[p][c])
{ nxt[p][c] = now;
p = fail[p];
}
if (!p) fail[now] = root;
else
{ int q = nxt[p][c];
if (len[q] == len[p] + 1)
fail[now] = q;
else
{ int u = newnode(len[p] + 1);
for (int i = 0; i < 2; i++) nxt[u][i] = nxt[q][i];
fail[u] = fail[q];
fail[now] = fail[q] = u;
while (p && nxt[p][c] == q)
{ nxt[p][c] = u;
p = fail[p];
}
}
}
return now;
}
} void insert(char *s)
{ int Len = strlen(s);
int last = root;
for (int i = 0; i < Len; i++)
last = add(last, s[i]);
} void work(char *str)
{ int cnt = 0;
int now = root;
int Len = strlen(str+1);
for (int i = 1; i <= Len; i++)
{ int c = idx(str[i]);
if (nxt[now][c])
{ cnt++;
now = nxt[now][c];
}
else
{ while (now && !nxt[now][c]) now = fail[now];
if (!now) { now = root; cnt = 0; }
else { cnt = len[now] + 1; now = nxt[now][c]; }
}
val[i] = cnt;
}
}
} tzw; int d[N];
int Q[N], hd, tl;
bool check(char *s, int lim)
{ int Len = strlen(s+1);
for (int i = 0; i <= lim; i++) d[i] = 0;
hd = 0, tl = 1;
for (register int i = lim; i <= Len; i++)
{ d[i] = d[i-1];
if (i > lim) //这里一定不能去掉, 去掉会RE
{ while (hd < tl && Q[hd] < i-val[i]) hd++;
while (hd < tl && d[Q[tl-1]]+i-Q[tl-1] < d[i-lim]+i-(i-lim)) tl--;
Q[tl++] = i - lim;
}
if (val[i] >= lim) d[i] = max(d[i], d[Q[hd]] + i - Q[hd]);
}
return 10*d[Len] >= 9*Len;
} int solve(char *s)
{ int l = 1, r = strlen(s+1);
while (l <= r)
{ int mid = (l+r) >> 1;
if (check(s, mid)) l = mid + 1;
else r = mid - 1;
}
return r;
} char str[N]; int main()
{ scanf("%d %d", &n, &m);
tzw.init();
for (register int i = 1; i <= m; i++)
{ scanf("%s", str);
tzw.insert(str);
}
for (register int i = 1; i <= n; i++)
{ scanf("%s", str+1);
tzw.work(str);
if(!check(str, 1)) puts("0");
else printf("%d\n", solve(str));
}
return 0;
}

备注

注释里的坑我全踩了

【BZOJ2806】【CTSC2012】Cheat 广义后缀自动机+二分+Dp的更多相关文章

  1. 【BZOJ2806】[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化DP

    [BZOJ2806][Ctsc2012]Cheat Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数接下来M行的01串,表示标准作文库接下来N行的 ...

  2. BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...

  3. BZOJ2806 [Ctsc2012]Cheat 【后缀自动机 + 二分 + 单调队列优化DP】

    题目 输入格式 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库 的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 输出格式 N行,每行一个整数,表示这篇作文的 ...

  4. BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]

    2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...

  5. bzoj 2806 [Ctsc2012]Cheat——广义后缀自动机+单调队列优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2806 只想着怎么用后缀数据结构做,其实应该考虑结合其他算法. 可以二分那个长度 L .设当前 ...

  6. BZOJ.2806.[CTSC2012]Cheat(广义后缀自动机 DP 单调队列)

    题目链接 首先二分答案L.然后就是判断能否将原串划分出一些长度不小于L的子串,这些子串要是给定n个串中的某个串的子串,且满足它们的长度之和不小于原串长度的90%. 贪心多长选一段什么的显然不对.老老实 ...

  7. 【BZOJ2806】Cheat(后缀自动机,二分答案,动态规划,单调队列)

    [BZOJ2806]Cheat(后缀自动机,二分答案,动态规划,单调队列) 题面 BZOJ 洛谷 题解 很有趣的一道题啊 对于在所有的串上面进行匹配? 很明显的后缀自动机 所以先构建出广义后缀自动机 ...

  8. [CTSC2012]熟悉的文章(广义后缀自动机+二分答案+单调队列优化DP)

    我们对作文库建出广义后缀自动机.考虑用\(SAM\)处理出来一个数组\(mx[i]\),表示从作文的第\(i\)个位置向左最远在作文库中出现的子串的长度.这个东西可以在\(SAM\)上跑\(trans ...

  9. 【BZOJ2806】【CTSC2012】Cheat - 广义后缀自动机+单调队列优化DP

    题意: Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 Output N行 ...

随机推荐

  1. 三星A3、A5、A7、G7、J5、J7、S6系列等新机型的部分手机解锁 ROOT刷机

    三星A3.A5.A7.G7.J5.J7.S6系列等新机型的部分手机,三星官方加了限制,需要解锁后才能刷机如果没有解锁,刷第三方recovery或者刷非官方原版固件,都会刷不进,手机跳转到提示界面,显示 ...

  2. Android 解析XML—pull解析方式

    在Android中,常见的XML解析器分别为SAX解析器.DOM解析器和PULL解析器,其中PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部 ...

  3. C#程序集版本控制文件属性祥解

    using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices ...

  4. django分页功能,templatetags的应用

    django 将不会将得到的html代码自动转化 from django.utils.html import format_html html =''' <a href='http://www. ...

  5. webstorm界面主题

     http://www.webstormthemes.com/ 

  6. 阿里P7架构师详解微服务链路追踪原理

    背景介绍 在微服务横行的时代,服务化思维逐渐成为了程序员的基本思维模式,但是,由于绝大部分项目只是一味地增加服务,并没有对其妥善管理,当接口出现问题时,很难从错综复杂的服务调用网络中找到问题根源,从而 ...

  7. matlab 读取输入数组

    In an assignment A(I) = B, the number of elements in B and I must be the same MATLAB:index_assign_el ...

  8. jQuery动态效果

    1.一号店首页 2.淘宝网购物车

  9. 那么再会吧!OI!(HNOI2019退役记)

    现在是4月7号7点. 退役了. 至此,整个LSOI17届全部毕业. 想说些什么呢?不知道啊. day1紧张过头,真正开始了解题意是在11点以后.半路忘了kmp怎么打,第一题计算几何根本没管,好啊,第三 ...

  10. 5G的前景以及意义

    首先来介绍一下5G:5G网络是第五代移动通信网络,其峰值理论传输速度可达每8秒1GB,比4G网络的传输速度快数百倍.举例来说,一部1G的电影可在8秒之内下载完成. 5G的技术原理是:三星电子通过研究和 ...