【后缀自动机】CodeForces 452E Three strings
通道:http://codeforces.com/problemset/problem/452/E
题意:给了三个串,问对于长度为l的串,满足(i1,i2,i3)(s1[i1..i1+l-1]==s2[i2...i2+l-1]==s3[i3+...i3+l-1])有多少组,输出长度为1-min(|s1|,|s2|,|s3|)的有多少组。
思路:对3个串共同建立SAM.每串末尾加个标记,然后dp[i][j]:i节点j串出现了多少次(0<=j<3),这个从底往上更新就可以了。然后用Num[i]记录长度为i的字符串有多少个,这样就得到了答案。
代码:https://github.com/Mithril0rd/Rojo/blob/master/cf452e .cpp
TAG:3串长度任意公共子串
以下是后缀数组做法:
思路:对高度数组的排名进行操作。我们首先得到c[i][j]表示排名为1~i的1,2,3串分别有多少个,j就记录1,2,3的状态,还有就是v[i]记录lcp值为i的有哪些。然后假如3个串都同一个字符,那么答案就是d=l1*l2*l3,所以当我们求长度为1的有多少个的时候,肯定就是分别在1,2,3串中同时出现且不重复的字符,那么计算1的时候就是把减去lcp为0的就可以了,计算2的时候就是减去lcp为1的。。。所以现在的重点就是怎么计算这个数量。我们首先用set维护一对(1,n),计算1的时候,我们依次弹出v[0]里面的全部位置,然后二分这个位置,计算是否符合,然后加入到结果中。(hint:因为这题要三串共有,所有要用类似前缀和的思想)
代码:https://github.com/Mithril0rd/ComplexCode/blob/master/cf452e.cpp