题意要求所有的T中的循环串在S中出现了多少次,多次出现重复计数。
先考虑处理循环串,我们可以把循环串往后复制一遍变成定长单串,这时候如果我们可以把处理定长单串的方法搞出来就也能搞出来循环了。现在考虑的是对于一个串T,以T[i]为结尾的长为n的串出现了几次。很容易想到用endpos的大小去求,所以应该先把endpos大小求出来,之后就是应该确定是哪个endpos。可以先考虑如何求出对于T[i]来说与S的最长公共子串,这时候只要在SAM上顺着fa树走一直到走到原点或者有可以往后转移就可以了。如果走到了根节点还是没有能转移的,那就说明就没有这个字符,直接全0就可以了。注意这时候的长度可能过大,也就是stl超过了n,而在计算的时候应该是只需要“刚刚好包含长度为n”的那个状态节点的endpos。所以需要再顺着fa往前跳到fa的len小于n就可以了。然后这时候还有一个重复计算的问题,这是由于循环串可能有重复产生的,这时候我们就得给同样的条件打上标记了,而怎么判断是同样的呢?显然当串相同的时候一定会走到相同的节点上,只需要在最后的+环节打标记就可以了。
wa点主要出在指针和状态下标的转换上以及数组的长度上,注意循环串要复制一遍的话得是2倍长度。。。emmm
#include
#include
#include
#include