题目

(夢の中で逢った、ような……)

「Madoka,不要相信 QB!」伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约。

这是 Modoka 的一个噩梦,也同时是上个轮回中所发生的事。为了使这一次 Madoka 不再与 QB 签订契约,Homura 决定在刚到学校的第一天就解决 QB。然而,QB 也是有许多替身的(但在第八话中的剧情显示它也有可能是无限重生的),不过,意志坚定的 Homura 是不会放弃的——她决定消灭所有可能是 QB 的东西。现在,她已感受到附近的状态,并且把它转化为一个长度为 \(n\) 的字符串交给了学 OI 的你。

现在你从她的话中知道,所有形似于 \(A+B+A\) 的字串都是 QB 或它的替身,且 \(|A|\ge k,|B|\ge 1\) (位置不同其他性质相同的子串算不同子串,位置相同但拆分不同的子串算同一子串),然后你必须尽快告诉 Homura 这个答案——QB 以及它的替身的数量。

\(n\le 1.5\times 10^4, k\le100\)。

注:本题小常数\(O(n^2)\)可过。

Homura不是有回溯时间的能力么。

分析

这个\(A+B+A\)的定义和KMP中的next数组太像了。

我们枚举左端点,先假设我们要判断\([1,r]\)是否合法。

若当前的next值留不出\(B\)的位置,我们需要缩小范围,因为next数组是最长的相同前后缀的长度,而我们要缩小它。

显然的,若\(\rm next[r-1] = p\),则代表\([1,p]=[r-p,r]\),且任意的相同前缀后缀的长度都不会大于这个\(p\)。

我们考虑若有\(q<p,[1,q]=[r-q,r]\),则有\([1,q]=[p-q,p]\),所以问题等价于找\([1,p]\)之间的最长的相同前后缀,为最大的\(q\)(因为我们要让\(|A|\ge k\))。

规模成功缩小,只要找到一个留的出\(B\)且\(|A|\ge k\)的一个答案即可统计。

然而,我们发现这样做,时间复杂度是要到\(O(n^3)\)的。

我们只要记录以下满足\(|A|\ge k\)的最小的点,然后直接用就可以了。

时间复杂度\(O(n^2)\)。

伪代码

\[\begin{split}
& \mathbf{Input} :\text{字符串S}\\
& \mathbf{Output} :\text{返回[0,0],[0,1]... [0,|S|]中有几个这样的子串,并处理next数组}\\
\\
1 &\ \mathbf{Function} \;\rm GetNext(S) \;\{ \\
2 &\ \rm \quad j := -1,\; ans := 0 \\
3 &\ \rm \quad \text{For i in [1,n]} \\
4 &\ \rm \quad \quad v := j \\
5 &\ \rm \quad \quad if \; j < k \\
6 &\ \rm \quad \quad \quad v := \infty \\
7 &\ \rm \quad \quad if\; j \ge 0 \\
8 &\ \rm \quad \quad \quad last[i] := min(last[j],\;v) \\
9 &\ \rm \quad \quad else \\
10 &\ \rm \quad \quad \quad last[i] := v \\
11 &\ \rm \quad \quad \text{if } i \le (i - 1) \div 2 \\
12 &\ \rm \quad \quad \quad ans := ans + 1\\
13 &\ \rm \quad \quad While\; j \ge 0 \text{ and S[i]}\not =S[j] \\
14 &\ \rm \quad \quad \quad j := next[j] \\
15 &\ \rm \quad \quad j := j + 1 \\
16 &\ \rm \quad \quad next[i + 1] := j \\
17 &\ \rm \quad return\;ans\\
18 &\ \} \\
\end{split}
\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \quad
\]

C++代码

#include <bits/stdc++.h>

using std::cin;
using std::cout; const int MAXN = 2e4 + 7;
const int inf = 0x3f3f3f3f; int k; int getnext(std::string s) {
static int nxt[MAXN], last[MAXN];
int ans = 0;
nxt[0] = -1;
for(int i = 0, j = -1; i <= s.length(); i++) {
int v = (j >= k ? j : inf);
last[i] = (j >= 0 ? std::min(last[j], v) : v);
ans += (last[i] <= (i - 1) / 2);
while(j >= 0 && s[j] != s[i]) j = nxt[j];
nxt[i + 1] = ++j;
}
return ans;
} int main() {
int ans = 0;
std::string s;
cin >> s >> k;
for(int i = 0; i < s.length(); i++) {
ans += getnext(s.substr(i));
}
cout << ans << std::endl;
return 0;
}

拓展

NOI 2014 动物园

【BZOJ 3620】似乎在梦中见过的样子的更多相关文章

  1. [BZOJ 3620] 似乎在梦中见过的样子 【KMP】

    题目链接:BZOJ - 3620 题目分析 这道题使用 KMP 做 O(n^2) 的暴力就能过. 首先,我们依次枚举字串左端点 l ,然后从这个左端点开始向后做一次 KMP. 然后我们枚举右端点 r  ...

  2. bzoj 3620 似乎在梦中见过的样子(KMP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3620 [题意] 给定一个字符串,统计有多少形如A+B+A的子串,要求A>=K,B ...

  3. bzoj 3620: 似乎在梦中见过的样子

    Description "Madoka,不要相信 QB!"伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约. 这是 Modoka 的一个噩梦,也同时是上个轮回 ...

  4. BZOJ.3620.似乎在梦中见过的样子(KMP)

    题目链接 /* 896kb 6816ms A+B+A是KMP的形式,于是固定左端点,对于每个位置i,若fail[i]所能到的点k中(k=fail[fail[fail[...]]]),有满足len(l~ ...

  5. BZOJ 3620: 似乎在梦中见过的样子 [KMP 暴力]

    和我签订契约,成为魔法少女吧 题意:求所有形似于A+B+A 的子串的数量 , 且len(A)>=k,len(B)>=1 位置不同其他性质相同的子串算不同子串,位置相同但拆分不同的子串算同一 ...

  6. 【BZOJ 3620】 3620: 似乎在梦中见过的样子 (KMP)

    3620: 似乎在梦中见过的样子 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 755  Solved: 445 Description “Madok ...

  7. BZOJ 3620: 似乎在梦中见过的样子

    似乎在梦中见过的样子.... 一道水题调了这么久,还半天想不出来怎么 T 的...佩服自己(果然蒟蒻) 这题想想 KMP 但是半天没思路瞟了一眼题解发现暴力枚举起始点,然后 KMP 如图: O( n2 ...

  8. 【kmp】似乎在梦中见过的样子

    参考博客: BZOJ 3620: 似乎在梦中见过的样子 [KMP]似乎在梦中见过的样子 题目描述 「Madoka,不要相信QB!」伴随着Homura的失望地喊叫,Madoka与QB签订了契约. 这是M ...

  9. 【BZOJ3620】似乎在梦中见过的样子 KMP

    [BZOJ3620]似乎在梦中见过的样子 Description “Madoka,不要相信 QB!”伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约. 这是 Modoka 的一个 ...

  10. BZOJ_3620_似乎在梦中见过的样子_KMP

    BZOJ_3620_似乎在梦中见过的样子_KMP Description “Madoka,不要相信 QB!”伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约. 这是 Modoka ...

随机推荐

  1. Python开发环境Wing IDE搜索工具介绍

    Wing IDE编辑器的搜索工具提供了一个基于友好GUI的搜索和替换工具. 某些情况下搜索可能会跨越整个文件,也有可能被限制到当前所选择的区域:可以区分大小写,也可以设置为不区分:可以被限制为只匹配整 ...

  2. OSS基本概念介绍

    存储空间(Bucket): 存储空间是用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间. 可以设置和修改存储空间属性用来控制地域.访问权限.生命周期等,这些属性设置直接作用于该存 ...

  3. 【Android开发笔记】底部菜单栏 FragmentTabHost

    公司项目,需求本来是按照谷歌官方指南写的,菜单栏设计成在导航栏下方 结果呢,审评时,BOSS为了和iOS统一,改成了底部菜单栏(标准结局),我只能呵呵呵呵呵呵呵 查了查资料发现实现底部菜单栏用的是Fr ...

  4. ajax请求总是返回error的问题

    多半是因为返回值格式的问题,在后台返回的应与前台设定的值一直,不然就会进入error,会报404服务器错误,极有可能是后台返回的数据类型不对 public void exitSystem( HttpS ...

  5. php-7.1.11编译选项配置

    ./configure \ --prefix=/usr/local/php-7.1.11 \ --with-config-file-path=/usr/local/php7.1.11/etc \ -- ...

  6. SQL Server(第二章) 字符串函数、日期时间函数、转换函数

    --1.CONCAT 函数:字符串连接(支持sql server2012 SQL规则 如果与NULL连接返回NILL) SELECT empid,CONCAT(firstname,lastname) ...

  7. 360、IE等浏览器对bootstrap的影响

    笔者开发的web程序部署上线后发现,bootstrap的菜单不显示,开发时候用chrome没有发现问题,在360浏览器上跑,发现360默认的是兼容模式,切换到极速模式就能够显示菜单了. 但是这样的用户 ...

  8. 那些年,被我蠢哭了的php代码小错误~~~

    首先,我爱敲代码!!!而且我很喜欢修改bug,在看到那些bug的时候,我是兴奋的,毕竟当你解决这个bug之后感觉是很爽的. 在学习的过程中,看到无数的bug,有一些错误是很微小的,一般在PHP中都能通 ...

  9. “ipconfig不是内部命令或外部命令”解决方法

    第一:用鼠标右键单击“计算机”,在弹出的下拉菜单中选择“属性”. 第二:在系统属性中选择“高级系统设置”.在系统属性对话框中找到其上方的“高级”选项卡,里面有一个“环境变量”按钮,点击进入 第三:在下 ...

  10. 2018.5.20 oracle强化练习

    --现在有一个商店的数据库,记录客户以及购物的情况, 商品表goods (商品号 goodsid varchar2(8) 商品名 goodsname varchar2(20) 单价 unitprice ...