时间限制: 5000MS | | 内存限制: 65536K |
提交总数: 11942 | | 接受: 4051 |
描述
字符串T的子字符串被定义为:
Ť ( 我 , ķ )= Ť 我 Ť 我 1 ... Ť I + K -1 ,1≤ 我 ≤ I + K -1≤| T |。 给定两个字符串A,B和一个整数K,我们定义S,一组三元组(i,j,k):
S = {( i , j , k )| ķ ≥ ķ , 甲 ( 我 , ķ )= 乙 ( Ĵ , ķ )}。 你要给的价值| S | 特定甲,乙和ķ。
输入
输入文件包含几个数据块。对于每个块,第一行包含一个整数ķ,随后包含字符串两行阿和乙分别。输入文件以K = 0 结尾。
1≤| A |,| B | ≤10 5
1≤ ķ ≤ 分钟 {| A |,| B |} A和B的字符都是拉丁字母。 产量
示例输入
2aababaaabaabaa1XXXX0
示例输出
22五
蜜汁翻译。。额不要在意
挺难的一题,弱弱的我码了一个中午
首先后缀数组双串匹配,同样的操作,两串链接用一字符隔开,跑一遍sa
重点就是如何求出公共前缀大于等于K的子串数
首先如果lcp(i,j) = len 【len >k】那么len - 1也满足
所以对于lcp(i,j),它的贡献是len - k + 1
我们利用height数组分组,每一个组内的AB串都可以匹配,统计答案即可
但这样会T,因为这样做其实是O(n^2)的
怎么办呢?
我们需要维护一个单调栈,扫两次
第一次:对于每个A,统计它前面的B对于答案的贡献
我们知道两串在height数组之间的最小值即为其最长公共前缀长度,
对于A前第一个B之后的一个最小值,一定会影响到之前左右的B,但是B与B之间的最小值只会影响到前面的B而不影响到后面的B
因此我们维护一个单调递增单调栈,如果当前height比栈顶小,那么栈顶所对应的那些后缀会受到此height的影响【 因为之前的B到后面的A一定会跨过这个地方,而这个地方height较小】,就合并栈顶【注意是合并】
看代码吧
#include #include #include #include