> 文章列表 > 【学习笔记】[JSOI2019]节日庆典

【学习笔记】[JSOI2019]节日庆典

【学习笔记】[JSOI2019]节日庆典

我觉得很厉害。因为这道字符串题目的分析非常自然而且并不复杂。

考虑枚举右端点到rrr时,维护可能成为答案的位置的集合。显然对于相邻两个元素i,ji,ji,j,我们有lcp(S[i:],S[j:])>r−j\\text{lcp(S[i:],S[j:])}>r-jlcp(S[i:],S[j:])>rj,否则可以删去i,ji,ji,j其中之一。画图不难发现我们只需要保证对于任意kkk,满足lcp(S[i:],S[k:])>r−k\\text{lcp(S[i:],S[k:])}>r-klcp(S[i:],S[k:])>rk,也就是只用和第一个位置进行比对。注意lcp\\text{lcp}lcp的长度是不随右端点rrr变化的,可以看成常数。

当然,上述分析并不能导向一个正确的解法。假设我们已经维护出来了上述集合,有一个非常套路的想法,假设已经检查完了iii之前的所有位置,那么对于之后的一个位置jjj,假设j−i<r−jj-i<r-jji<rj,那么不难发现S[i:j)=S[j:2j−i)S[i:j)=S[j:2j-i)S[i:j)=S[j:2ji),我们记这一段为AAA(更确切地说AAAS[i:r]S[i:r]S[i:r]的周期),2j−i2j-i2ji以后的为BBB,那么我们得到A+A+B,A+B+A,B+A+AA+A+B,A+B+A,B+A+AA+A+B,A+B+A,B+A+A三种方案。容易观察出中间那种肯定是不优的,也就是jjj一定不优。那么有2j≥r+i2j\\ge r+i2jr+i,显然只有最多log⁡\\loglog个需要检查,这道题就做完了。因为lcp\\text{lcp}lcp已经匹配到了底所以用zzz函数辅助检查一下即可。

复杂度O(nlog⁡n)O(n\\log n)O(nlogn)

代码咕了。其实是我不会打zzz函数

至于维护集合那个部分,可以自己编一个做法,事实上发现每次暴力重构就完了。