【后缀自动机】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]表示排名为1i123串分别有多少个,j就记录1,2,3的状态,还有就是v[i]记录lcp值为i的有哪些。然后假如3个串都同一个字符,那么答案就是d=l1*l2*l3,所以当我们求长度为1的有多少个的时候,肯定就是分别在1,2,3串中同时出现且不重复的字符,那么计算1的时候就是把减去lcp0的就可以了,计算2的时候就是减去lcp1的。。。所以现在的重点就是怎么计算这个数量。我们首先用set维护一对(1,n),计算1的时候,我们依次弹出v[0]里面的全部位置,然后二分这个位置,计算是否符合,然后加入到结果中。(hint:因为这题要三串共有,所有要用类似前缀和的思想)

代码:https://github.com/Mithril0rd/ComplexCode/blob/master/cf452e.cpp

posted @ 2014-10-17 21:08  mithrilhan  阅读(285)  评论(0编辑  收藏  举报