【题目描述】

  给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度。给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个。N,M,K<=200000

【解】

  这是道非常好的kmp题,感觉做了之后对kmp有了新认识。。。看到马上kmp,首先当我们在A串上用B串跑一遍kmp,我们会得到一个数组,也就是在A串上以i为结尾的字串长度为A[i]的后缀等于B串长度为A[i]的前缀。那么在这个时候我们用一个cnt数组统计每个长度出现的次数。但统计完我们发现我们还漏了一些,因为B里会有后面的字串和开头字串一样的情况,而原始数组统计的是最大匹配长度,这个时候我们可以利用B串的自匹配数组。

for (i = m; i >= 1; i--)
    cnt[kmp[i]] += cnt[i];//kmp是B的自匹配数组

因为B串的前kmp[i]位和后kmp[i]为是一样的,也就是说当A串和B串的i位匹配时,以i为结尾的后kmp[i]位也可以和B串的前kmp[i]位匹配,原始数组因为统计的最大匹配长度漏统计了这种情况,进行该项操作后就不会漏掉了。

最后因为题目要求匹配长度恰好为x,然而cnt数组中存储的cnt[i],必然包含了cnt[i + 1]及以上的情况,所以我们输出的时候输出cnt[i] - cnt[i + 1],因为cnt[i]中可以扩展的字串必然都包含于cnt[i + 1]。

posted on 2016-09-24 20:56  appgle  阅读(247)  评论(0编辑  收藏  举报