首先差分,问题转化为求一个字符串中有多少对本质相同且不相交不相邻的子串(与 (n2) 的和)。
对于前缀 i,j (i>j),考虑统计它们的所有公共后缀的贡献。
设 l 为后缀长度,len 为 i,j 的最长公共后缀长度(即 Parent Tree 上的 LCA 包含子串的最长长度)。
则有 j+1<i−l+1,即 l<i−j。
而又有 l≤len。
故 i,j 的贡献应为 min(i−j−1,len)。
考虑静态链分治确定 LCA,那么考虑对于子树内的前缀 i,计算所有与它不在同一棵子树内的 j 的贡献:
- 若 i−len≤j<i,其贡献为 i−j−1;
- 若 j<i−len,其贡献为 len;
- 若 i<j≤i+len,其贡献为 j−i−1;
- 若 j>i+len,其贡献为 len。
于是链分治时对 endpos 维护一棵线段树和一个 vector 即可。
代码:
1 |
|