【BZOJ4560】[NOI2016]优秀的拆分
题面
bzoj
洛谷
题解
考虑一个形如\(AABB\)的串是由两个形如\(AA\)的串拼起来的
那么我们设
\(f[i]\):以位置\(i\)为结尾的形如\(AA\)串的个数
\(g[i]\):以位置\(i\)为开头的形如\(AA\)串的个数
\[ \therefore Ans=\sum_{i=1}^nf[i]*g[i+1] \]
题目的难点转化为求\(f,g\)。
但是,其实我们只要\(O(n^2)\)暴力求一下就有\(95pts\)了,
所以我们接下来考虑最后的\(5pts\)怎么拿:
我们枚举\(A\)的长度\(len\)
将所有位置为\(len\)的倍数的点设为关键点,
则如果一个\(AA\)满足要求
这个\(AA\)必过两个关键点,
那么我们要算的就是相邻两个关键点对答案的贡献:
记相邻两个关键点为\(,i,j\)那么\(j=i+len\)
记\(Lcp=lcp(suf(i), suf(j)),Lcs=lcs(pre(i-1),pre(j-1))\)
那么,如果\(Lcp+Lcs,则不能构成\(AA\)
为什么呢?
相当于这样一种情况:
\[ \underbrace{.......i-1}_{Lcs}\;\overbrace{\underbrace{i........}_{Lcp}\;....\underbrace{.......j-1}_{Lcs}}^{len}\;\underbrace{j........}_{Lcp} \]
这样子是不合法的。
反之,中间两段的\(Lcp,Lcs\)会有交,而我们这个\(A\)串的终点落在中间长度为\(Lcp+Lcs-len+1\)的交上都是可以的
因为这样的话平移一下可以保证紧跟着出现一个不重叠的\(A\)串
又因为串\(A\)起点和终点分别出现的位置是一段区间,所以直接分别在\(f,g\)上差分即可
复杂度是调和级数\(O(nlogn)\)。
具体细节看代码:
#include
#include
#include
#include
#include
#include
#include