看了一圈题解没有后缀自动机的题解,不过毕竟后缀自动机后缀数组一家人,这里和大家分享后缀自动机的做法。
思路是一样的,处理出有多少个AA串以i开头,记做f[i],有多少个AA串以i结尾,记做g[i],那么ans就是所有的g[i]f[i+1]
以下用pre(i)表示以i结尾的前缀,suffix(i)表示以i开头的后缀。
怎么去求g与f数组呢,考虑AA的拼接,设它的接点是第二个A开始的位置。设一个A的长度为L,那么对于一个长度为L的区间[i,j]来说,设pre(i-1)与pre(j-1)的最长公共后缀长度为x suffix(i)与suffix(j)的最长公共前缀长度为y,那么[j-x,i+y+1]都能作为接点(注意[i-x,i+y-1] 与 [j-x,j+y-1]是相同的子串
为了不统计重,区间[i,j]只统计接点在[i,j]范围内的AA串,所以x与L取min,y与L-1取min。
现在问题的步骤便出来了: 1.枚举一个A的长度L。
2.枚举i=KL,j=i+L,统计接点在区间[i,j]中的AA串对于f与g的贡献:
3.查询x与y,定义如上所示。
4.如果x+y<L,接不上,没有贡献。
5.否则每个[i-x,i-x+(x+y-L)]区间内的点都能作为AA串的左端点,当然,其右端点为[j+y-1-(x+y-L),j+y-1],建议画图理解。发现每个区间对于f与g的贡献相当于一个区间加1,所以差分点修改。
6.最后统计前缀和即可求出f与g数组。ans=所有g[i]f[i+1]
那么问题的关键是:怎么求前缀的最长公共后缀?后缀数组可以,当