又看错题了……这个毛病不改不行啊。所幸没差太远。以后写题解我决定加上“题意简述”。
题意:给一个字符串s,长度L不超过1百万,记所有既是子串s[0..i]的前缀,又是其后缀,且该前缀、后缀不重叠的字符串的数量为num[i],求num[0], num[1], …, num[L-1]之积对某个给定大质数取模的结果。多组数据。
题面中给了背景:KMP算法。于是我把“数量”当成了“最大长度”。
在《NOI导刊》的培训班听老师讲过,但是没搞清楚……又拿出来想了想。
如果不考虑“前缀、后缀不重叠”,并且不等于整个子串,怎么求这样的字符串的数量?跑KMP的时候递推一个数组cnt,表示沿next数组从i跳转有多少次成功匹配,即为所求。因为每跳转一次,相当于找到一个前缀=后缀;cnt[0] = 0。
如果加上这个限制呢?
先跑一遍KMP,求出next和上述cnt。再跑一遍,只是在跳转的条件中加上j*2 >= i
,每次停下来之后更新答案。注意,cnt不计s[0..j],所以这里要+1。
抛开这道题,把next[i]定义为真前缀等于后缀的最大长度有点别扭……跳出while
循环后,j=0
既可能代表成功匹配到s[0],也可能代表没有匹配。把next[i]定义为在i处失配后下一个比较的位置,并且置next[0] = -1可能会好一些。
#include <cstdio></