题目连接:
https://vjudge.net/problem/SPOJ-NSUBSTR
Description
You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string ‘ababa’ F(3) will be 2 because there is a string ‘aba’ that occurs twice. Your task is to output F(i) for every i so that 1<=i<=|S|.
Input
String S consists of at most 250000 lowercase latin letters.
Output
Output |S| lines. On the i-th line output F(i).
Sample Input
ababa
Sample Output
3
2
2
1
1
Hint
题意
求一个关于串的函数F,F[i]表示串中长度为i的子串出现的最多次数
题解:
这题就是求后缀自动机每个点的Right大小,因为每个endpos类表示的是出现次数及位置一样的一类子串,设一个endpos类中的字符串最长
的长度为len[i],最短为minlen[i], 所以更新时应更新$ F[j] = max(F[j], |Right[i]|) j \in [minlen[i], len[i]] $,但其实不必每个都更新,因为如果长度为n的字符串出现了m次,那么长度为n-1的字符串一定至少出现了m次,及$ F[i] >= F[j] (i < j) $,所以对于每个点只需要更新$ F[len[i]] = max(F[i],|Right[i]|) $,最后从大到小更新一下F就好了。
然后就是求解Right大小,先对所有前缀节点赋1,然后自底向上更新right($ Right[i] = \sum_{edge[i]} Right[j] $),为了保证Right正确需要以拓扑序更新Rgiht,也就是len[i]大的节点先更新,因为len[i] > len[fa[i]],len越大的节点越靠近parent tree底部
代码
1 |
|