我的做法是这样的:
把两个串拼一块,搞出后缀数组,对于A的每个长度>=k的后缀i(它对应了一个长度=k的子串),去找一个在后缀数组中离它最近的后缀j(这样能使两者的LCP尽可能大),这可以二分,这个j对应了B的一个长度=k的子串,然后把(i,j)塞到大根堆里。每次贪心找LCP最大的一对,把答案加上k−LCP(i,j)。
但是这样有可能j已经被别的i用过了,这时我直接让i再在后缀数组上找一个此时没被用过的且离它最近的j,然后重新扔到堆里。
然而我写着写着就发现它的复杂度是假的,因为一个j可能会被很多个i指向,当j被取出后,可能会引起很多的“重新找个没被用过的j扔到堆里”的操作,出堆次数会被卡成O(n2)。
然后我写完之后交上去试了试……它A了……
然后我随便构造了一个n=150000,k=3,两个字符串里全是a的数据,造了个私题在luogu评测机上试了下,发现这样即使开O2我的假做法也要跑到1s多,而使用SAM的题解仅20多ms……
输入数据
(输出数据仅有一个数 0)
我的假做法代码