[JSOI2019]节日庆典

38 篇文章 0 订阅

题目

传送门 to LOJ

传送门 to luogu

题目概要
对于字符串 S S S 的每个前缀,求出循环移位后可以得到的最小字典序,输出向左的循环移位长度。如果有多个,输出最小的向左循环移位长度。

数据范围与提示
∣ S ∣ ≤ 3 × 1 0 6 |S|\le 3\times 10^6 S3×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::])rj 时,无论 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::])>rj(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::])>rk 的话,肯定也满足 l c p ( S [ j : : ] , S [ k : : ] ) > r − k lcp(S[j::],S[k::])>r-k lcp(S[j::],S[k::])>rk 了。所以,只需要和首个分界点进行比对

可是糟糕的是,我们没法维护单调栈了。虽说我们也并不需要维护单调栈,因为本题是查询完整的前缀。不管怎么说,我们要想办法找到 稳定的大小关系。接下来这一步,是如何想到的,我也不知道了。我只能说明它是正确的。

j − i < r − j j-i<r-j ji<rj 时,不难发现 j − i j-i ji S [ i : : ] S[i::] S[i::] 的一个周期。那么,可以考虑研究一下从 i i i 开始、从 j j j 开始、从 j + ( j − i ) j+(j-i) j+(ji) 开始,这三种情况。记这个周期为 A = S [ i : j − 1 ] A=S[i:j-1] A=S[i:j1] ,非周期部分 B = S [ 2 j − i : r ] + S [ 1 : i − 1 ] B=S[2j-i:r]+S[1:i-1] B=S[2ji:r]+S[1:i1] ,三种情况分别对应
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} ij2ji: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 2ji 更优。

有了这个结论,我们就可以说明 r − i ⩾ 2 ( r − j ) r-i\geqslant 2(r-j) ri2(rj) 进而说明 一共只有 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 下,不深究。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值