Idea: This question is the same as wikioi 1306. It is also the number of different substrings. However, wikioi takes a long time and then uses the trie tree. But when I used that code to submit this question, I became dizzy ...... Because there are multiple groups of examples for this question, it takes a little longer.
So of course this question is made with an array of suffixes!
Algorithm analysis:
Each substring must be the prefix of a suffix. The original problem is equivalent to finding the number of different prefixes between all suffixes. If all suffixes follow suffix (SA [1]), suffix (SA [2]), suffix (SA [3]),…, Suffix (SA [N]) sequence calculation, it is not difficult to find that for each newly added suffix (SA [k]), it will generate N-sa [k] + 1 new prefix. However, height [k] is the same as the prefix of the preceding string. Therefore, suffix (SA [k]) will "Contribute" the n-sa [k] + 1-height [k] Different substrings. The accumulated answer is the answer to the original question. The time complexity of this practice is O (n ).
See the figure below to better understand why n-sa [k] + 1-height, because of how many characters there are, of course, how many prefixes there are, that is, the sub-string, and the difference is to subtract the same prefix:
# Include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <map> # include <queue> # include <set> # include <cmath> # include <bitset> # define MEM (, b) memset (a, B, sizeof (A) # define lson I <1, L, mid # define rson I <1 | 1, Mid + 1, R # define llson j <1, L, mid # define rrson j <1 | 1, Mid + 1, R # define INF 0x7fffffff # define maxn 100010 using namespace STD; typedef long ll; typedef unsigned long ull; void R Adix (int * STR, int * a, int * B, int N, int m) {static int count [maxn]; MEM (count, 0 ); for (INT I = 0; I <n; I ++) ++ count [STR [A [I]; for (INT I = 1; I <= m; I ++) Count [I] + = count [I-1]; for (INT I = n-1; I> = 0; I --) B [-- count [STR [A [I] = A [I];} void suffix (int * STR, int * Sa, int N, int m) // calculate the suffix array SA {static int rank [maxn], a [maxn], B [maxn]; for (INT I = 0; I <N; I ++) rank [I] = I; Radix (STR, rank, SA, n, m); rank [SA [0] = 0; for (INT I = 1; I <N; I ++) rank [SA [I] = rank [SA [I-1] + (STR [SA [I]! = STR [SA [I-1]); For (INT I = 0; 1 <I <n; I ++) {for (Int J = 0; j <N; j ++) {A [J] = rank [J] + 1; B [J] = J + (1 <I)> = n? 0: rank [J + (1 <I)] + 1; SA [J] = J;} Radix (B, SA, rank, N, N ); radix (A, rank, SA, n, n); rank [SA [0] = 0; For (Int J = 1; j <n; j ++) rank [SA [J] = rank [SA [J-1] + (A [SA [J-1]! = A [SA [J] | B [SA [J-1]! = B [SA [J]) ;}} void calcheight (int * STR, int * Sa, int * H, int N) // obtain the longest public prefix array H {static int rank [maxn]; int K = 0; H [0] = 0; For (INT I = 0; I <N; I ++) rank [SA [I] = I; for (INT I = 0; I <n; I ++) {k = 0? 0: K-1; If (rank [I]) while (STR [I + k] = STR [SA [rank [I]-1] + k]) K ++; else K = 0; H [rank [I] = K ;}} int A [maxn], sa [maxn], height [maxn]; int main () {// freopen ("test.txt", "r", stdin); int t; scanf ("% d", & T); While (t --) {char s [50005]; scanf ("% s", S); int n = strlen (s); copy (S, S + n, a); suffix (, sa, N, 256); calcheight (A, SA, height, n); // For (INT I = 0; I <n; I ++) // cout