SPOJ694 DISUBSTR --- 后缀数组 / 后缀自动机

SPOJ694 DISUBSTR

题目描述:

Given a string, we need to find the total number of its distinct substrings.

输入格式:

T- number of test cases. T<=20;
Each test case consists of one string, whose length is <= 1000

输出格式:

For each test case output one number saying the number of distinct substrings.

翻译:

给定一个字符串,求该字符串含有的本质不同的子串数量。

后缀数组和后缀自动机都可做,但因为两者是不同的东西,不妨都谈谈。

后缀数组:

所有的子串数量为(n*(n+1)/2),只要去重即可

比如字符串ABABA,将其后缀排序后:

A
ABA
ABABA
BA
BABA

重复的子串一定是后缀的公共前缀。

如何正确的得到一个排序方式,来得到所有的重复子串呢?

注意到重复的子串说明了两者的前面有一截相似,也就是说,两者的排名相近。

那么将字符排序后,有重复前缀的定会排在一起。

其中height数组就是两者重复的子串数量。

如果一个后缀自己有很多重复子串呢?

如ABABAB

那么

ABABAB

ABAB

AB

这些height数组会一一将影响抵消

因此答案即为 (n*(n+1)/2 - sum_{i=1}^{n} height(i) )

后缀自动机:

非常简单粗暴,相同的子串出现的(right)集合一定相同,

所以只要根据每个(right)集合的(max - min)统计即可

(对于本题而言,由于字符集太大(128),所以用后缀自动机做不太好)

或者用后缀自动机建出后缀数组来求height

注:SPOJ705为跟本题类似的题,但后缀自动机无法通过

后缀数组代码

原文地址:https://www.cnblogs.com/reverymoon/p/8893638.html