卧薪尝胆,厚积薄发。
bzoj十连测第五场 可持久化字符串
Date: Mon Feb 25 20:10:16 CST 2019 In Category: NoCategory

Description:

一个 $S$ 的循环节 $T$ 表示为可以找到一个正整数 $k$ 使得 $S$ 是 $T^k$ 的前缀。一次操作会在字符串尾部添加一个字符,并且你需要在每次操作后输出最小循环节长度。要求可持久化与在线。
$1\leqslant n\leqslant 3\times 10^5$

Solution:

首先字符串形成了一个树的结构,答案是 $i-nxt[i]$ ,显然可以暴力 $KMP$ ,但 $KMP$ 的复杂度依赖均摊分析,这样复杂度是假的。
考虑怎么快速跳 $nxt$ ,如果 $c[j+1]=c[i]$ ,那么 $nxt[i]=j+1$ ,如果不等于的话,分类讨论一下:
如果 $2\times nxt[j]\leqslant j$ , $j=nxt[j]$ ,如果 $2\times nxt[j]>j$ ,那么显然 $j$ 有 $j-nxt[j]$ 这样一个循环节,考虑如果暴力跳过这些 $nxt$ 会发生什么,会发现其实是跳过了一个循环节,那么我们就不用一步一步跳,而是一下把这所有的循环节都跳过去,反正在循环节上 $j+1$ 永远不等于 $i$ ,即 $j=j\%(j-nxt[j])$ ,我们每次让 $j$ 至少缩小一半,因此至多跳 $\log$ 次,然后需要在线构造倍增定位节点就行了。
时间复杂度 $O(n\log^2n)$ 。

Code:



In tag: 字符串-KMP
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡