题目
题目概要
对于字符串
S
S
S 的每个前缀,求出循环移位后可以得到的最小字典序,输出向左的循环移位长度。如果有多个,输出最小的向左循环移位长度。
数据范围与提示
∣
S
∣
≤
3
×
1
0
6
|S|\le 3\times 10^6
∣S∣≤3×106 。
思路
字典序的变化其实并不复杂。就像区间字典序最大子串一样,从前缀 i i i 变为前缀 ( i + 1 ) (i{+}1) (i+1) 时,方案的变动很小。
沿用那道题的方法,枚举右端点
r
r
r 的同时,想办法维护 可能有用的答案集合。考虑两个分界点
i
,
j
(
i
<
j
)
i,j\;(i<j)
i,j(i<j) 是否有可能 “胜负已定” 。容易发现,当
l
c
p
(
S
[
i
:
:
]
,
S
[
j
:
:
]
)
≤
r
−
j
lcp(S[i::],S[j::])\le r-j
lcp(S[i::],S[j::])≤r−j 时,无论
r
r
r 再怎么增大,二者的大小关系都确定了。所以
l
c
p
(
S
[
i
:
:
]
,
S
[
j
:
:
]
)
>
r
−
j
(
i
<
j
)
lcp(S[i::],S[j::])>r-j\quad(i<j)
lcp(S[i::],S[j::])>r−j(i<j)
继续照搬那道题,考虑 l c p lcp lcp 的传递性。若还有分界点 k ( k > j ) k\;(k>j) k(k>j) 满足 l c p ( S [ i : : ] , S [ k : : ] ) > r − k lcp(S[i::],S[k::])>r-k lcp(S[i::],S[k::])>r−k 的话,肯定也满足 l c p ( S [ j : : ] , S [ k : : ] ) > r − k lcp(S[j::],S[k::])>r-k lcp(S[j::],S[k::])>r−k 了。所以,只需要和首个分界点进行比对。
可是糟糕的是,我们没法维护单调栈了。虽说我们也并不需要维护单调栈,因为本题是查询完整的前缀。不管怎么说,我们要想办法找到 稳定的大小关系。接下来这一步,是如何想到的,我也不知道了。我只能说明它是正确的。
当
j
−
i
<
r
−
j
j-i<r-j
j−i<r−j 时,不难发现
j
−
i
j-i
j−i 是
S
[
i
:
:
]
S[i::]
S[i::] 的一个周期。那么,可以考虑研究一下从
i
i
i 开始、从
j
j
j 开始、从
j
+
(
j
−
i
)
j+(j-i)
j+(j−i) 开始,这三种情况。记这个周期为
A
=
S
[
i
:
j
−
1
]
A=S[i:j-1]
A=S[i:j−1] ,非周期部分
B
=
S
[
2
j
−
i
:
r
]
+
S
[
1
:
i
−
1
]
B=S[2j-i:r]+S[1:i-1]
B=S[2j−i:r]+S[1:i−1] ,三种情况分别对应
i
:
A
+
A
+
B
j
:
A
+
B
+
A
2
j
−
i
:
B
+
A
+
A
\begin{aligned} i&:A+A+B\\ j&:A+B+A\\ 2j-i&:B+A+A \end{aligned}
ij2j−i:A+A+B:A+B+A:B+A+A
其实你一看就知道 j j j 肯定没用,把 B B B 放中间,人不人鬼不鬼的。不过还是给一个严谨证明。设 A A B > A B A AAB>ABA AAB>ABA(必须严格大于,等于的时候答案为 i i i),必然是 A B > B A AB>BA AB>BA ,后面同时接一个 A A A 得到 A B A > B A A ABA>BAA ABA>BAA 所以 2 j − i 2j-i 2j−i 更优。
有了这个结论,我们就可以说明 r − i ⩾ 2 ( r − j ) r-i\geqslant 2(r-j) r−i⩾2(r−j) 进而说明 一共只有 log r \log r logr 个有用的点,暴力检查就可以得到答案。咋检查啊?因为 l c p lcp lcp 已经匹配到了底,所以就是求一个 l c p ( S [ x : : ] , S [ 1 : : ] ) lcp(S[x::],S[1::]) lcp(S[x::],S[1::]) ,做一个扩展 K M P \tt KMP KMP 就行。(如果 x x x 又到了底呢?那 x x x 就变成了 S [ 1 : : ] S[1::] S[1::] 啊!)
复杂度 O ( n log n ) \mathcal O(n\log n) O(nlogn) 完成了所有事情。
2022/8/19 update \texttt{2022/8/19 update} 2022/8/19 update:看到个线性做法,只 m a r k \rm mark mark 下,不深究。