ArticleDirectory
Link: http://www.spoj.com/problems/DISUBSTR/
694. Distinct substringsproblem code: disubstr |
Given a string, we need to find the total number of its distinct substrings.
Input
T-Number of test cases. T <= 20;
Each test case consists of one string, whose length is <=1000
Output
For each test case output one number saying the number of distinct substrings.
Example
Sample input:
2
CCCCC
Ababa
Sample output:
5
9
Explanation for the testcase with string Ababa:
Len = 1: A, B
Len = 2: AB, Ba
Len = 3: ABA, bab
Len = 4: Abab, Baba
Len = 5: Ababa
Thus, total number of distinct substrings is 9.
/* * Spoj 694 * calculates the number of different substrings for a given string. * Each substring must be the prefix of a suffix. The original problem is equivalent to finding the number of different substrings with different suffixes. * The total number is N * (n-1)/2, and the sum of height [I] is the answer. */ # Include <Iostream> # Include < String . H> # Include <Algorithm> # Include <Stdio. h>Using Namespace STD; Const Int Maxn = 1010 ; /* * Suffix array * multiplyAlgorithmO (N * logn) * The length of the array to be sorted is N, which is placed between 0 and ~ In n-1, add 0 * build_sa (, n + 1,) at the end; // note that it is n + 1; * getheight (, n); * For example: * n = 8; * num [] = {1, 1, 2, 1, 1, 1, 1, 2, $}; note that the last digit of num is 0, other values greater than 0 * Rank [] = {4, 6, 8, 1, 2, 3, 5, 7, 0}; rank [0 ~ N-1] is a valid value. Rank [N] Must be 0. The value * Sa [] = {8, 3, 4, 5, 0, 6, 1, 7, 2} is invalid }; sa [1 ~ N] is a valid value, sa [0] Must be n is an invalid value * Height [] = {0, 0, 3, 2, 3, 1, 2, 0, 1 }; height [2 ~ N] is a valid value * */ Int Sa [maxn]; // Sa array, indicating to sort the N suffixes of S in ascending order // The starting position of the suffix is sequentially placed in SA. Int T1 [maxn], T2 [maxn], C [maxn]; // Evaluate the intermediate variable required by the SA array without assigning a value Int Rank [maxn], height [maxn]; // The string to be sorted is placed in the S array, from S [0] To s [n-1]. The length is n and the maximum value is less than M, // All s [I] Except S [n-1] are greater than 0, R [n-1] = 0 // After the function is completed, the result is placed in the SA array. Void Build_sa ( Int S [], Int N, Int M ){ Int I, j, P, * x = T1, * Y = T2; // In the first round of base sorting, if the maximum value of S is large, you can change it to quick sorting. For (I = 0 ; I <m; I ++) C [I] = 0 ; For (I = 0 ; I <n; I ++) C [x [I] = s [I] ++ ; For (I = 1 ; I <m; I ++) C [I] + = C [I- 1 ]; For (I = N- 1 ; I> = 0 ; I --) SA [-- C [x [I] = I; For (J = 1 ; J <= N; j <= 1 ) {P = 0 ; // Sort the second keyword directly using the SA Array For (I = N-J; I <n; I ++) y [p ++] = I; // The minimum number of J numbers after which the second keyword is null For (I = 0 ; I <n; I ++) If (SA [I]> = J) y [p ++] = sa [I]- J; // In this way, array y stores the result sorted by the second keyword. // First keyword of base sort For (I = 0 ; I <m; I ++) C [I] = 0 ; For (I = 0 ; I <n; I ++) C [x [Y [I] ++ ; For (I = 1 ; I <m; I ++) C [I] + = C [I- 1 ]; For (I = N-1 ; I> = 0 ; I --) SA [-- C [x [Y [I] = Y [I]; // Calculate the new array X based on the SA and array x Swap (x, y); P = 1 ; X [SA [ 0 ] = 0 ; For (I = 1 ; I <n; I ++ ) X [SA [I] = Y [SA [I- 1 ] = Y [SA [I] & Y [SA [I- 1 ] + J] = Y [SA [I] + J]? P- 1 : P ++ ; If (P> = N) Break ; M = P; // Maximum Value of next base sort }} Void Getheight ( Int S [], Int N ){ Int I, J, K =0 ; For (I = 0 ; I <= N; I ++) rank [SA [I] = I; For (I = 0 ; I <n; I ++ ){ If (K) k -- ; J = Sa [rank [I]- 1 ]; While (S [I + k] = s [J + k]) K ++ ; Height [rank [I] =K ;}} Char STR [maxn]; Int S [maxn]; Int Main (){ // Freopen ("in.txt", "r", stdin ); // Freopen ("out.txt", "W", stdout ); Int T; scanf ( " % D " ,&T ); While (T -- ) {Scanf ( " % S " , STR ); Int N = Strlen (STR ); For ( Int I = 0 ; I <= N; I ++) s [I] = STR [I]; build_sa (S, N + 1 ,128 ); Getheight (S, N ); Int Ans = N * (N + 1 )/ 2 ; For ( Int I = 2 ; I <= N; I ++) ans-= Height [I]; printf ( " % D \ n " , ANS );} Return 0 ;}