[POJ 3415]

Common Substrings

后缀数组

给出两个长度最多100,000的字符串s和t,求s和t中所有长度大于K的相同子串配对数。

做法首先是将s[sl]置最大值,并将t放在s[sl]后,计算后缀数组。接下来需要顺序遍历h[n],遍历到位置i时,如果sa[i]属于s,那么找出0到i-1中所有属于t且与s公共后缀长度>=m的子串,并将累计的配对数记录以类似计数排序的方式记录为ab[n]中,sa[i]对应满足题意的配对总数即为ab[h[i]]。如果sa[i+1]也属于s,且h[i+1]>=h[i],那么sa[i+1]对应的配对数和sa[i]是相同的;若h[i+1]<h[i],那么也能根据ab[h[i+1]]来O(1)地得到结果。

这里在更新ab[n]时本来应该是分成ab[2][n],分别对属于s和属于t的后缀分别维护配对总数的,这样根据平摊分析构造ab的总时间复杂度就是O(n),但实现起来细节太多了容易错。而现在这种偷懒的做法会导致当sa[i]、sa[i+1]、sa[i+2]……分别属于s、t、s……且都满足h[]>=m时,需要反复重新计算ab,但这种情况实际上较少出现,所以并不会慢上太多。

ps:上周刚赶完第二篇论文,以为可以稍微轻松点了,结果马上又被安排写专利…… 总不会到时候真的让我写第三篇吧?

ps2:另外,最近也在看毛姆的《月亮和六便士》