Spoj694 http://www.spoj.pl/problems/DISUBSTR/
Spoj705 http://www.spoj.pl/problems/SUBST1/
The two questions are similar, but only 705 of the data is a little bigger. There is no pressure to use the multiplier algorithm. Continue to set the template.
Stick to Luo danniu's idea. To put it bluntly, each Suffix of Σ is long-height.
Number of different substrings (spoj694, spoj705)
Returns the number of different substrings for a given string.
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]), 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 ).
Spoj 705
# Define maxn 50010int wa [maxn], WB [maxn], WV [maxn], WSS [maxn]; int R [maxn], sa [maxn]; int CMP (int * r, int A, int B, int L) {return R [a] = R [B] & R [A + L] = R [B + L];}/* [multiplier algorithm O (nlgn)] Put the string to be sorted in the r array, from R [0] To R [n-1], with a length of N and the maximum value less than m before the multiplication algorithm is used, make sure that the values of the r array are greater than 0. Then add a 0 character to the original string. If the length of the original string is N, the length of the r array constructed by the suffix array should be n + 1. therefore, when calling the DA function, the corresponding N should be n + 1. */void da (int * r, int * Sa, int N, int m) {// n should be added with 1 int I, j, P, * x = wa, * Y = WB, * t; for (I = 0; I <m; I ++) WSS [I] = 0; for (I = 0; I <N; I ++) WSS [x [I] = R [I] ++; for (I = 1; I <m; I ++) WSS [I] + = WSS [I-1]; for (I = n-1; I> = 0; I --) SA [-- WSS [x [I] = I; for (j = 1, P = 1; P <n; j * = 2, M = P) {for (P = 0, I = N-J; I <N; I ++) y [p ++] = I; for (I = 0; I <n; I ++) if (SA [I]> = J) Y [p ++] = sa [I]-J; for (I = 0; I <N; I ++) WV [I] = x [Y [I]; for (I = 0; I <m; I ++) WSS [I] = 0; for (I = 0; I <n; I ++) WSS [wv [I] ++; for (I = 1; I <m; I ++) WSS [I] + = WSS [I-1]; for (I = n-1; I> = 0; I --) sa [-- WSS [wv [I] = Y [I]; for (t = x, x = Y, y = T, P = 1, X [SA [0] = 0, I = 1; I <n; I ++) x [SA [I] = CMP (Y, sa [I-1], sa [I], j )? P-1: P ++;} return;} int rank [maxn], height [maxn]; // rank [I]: the number of the I-th row; SA [I]: where is the suffix string of the column I? inverse void calheight (int * r, int * Sa, int N) for each other {// n no 1 int I, j, k = 0; for (I = 1; I <= N; I ++) rank [SA [I] = I; for (I = 0; I <N; height [rank [I ++] = k) {for (K? K --: 0, j = sa [rank [I]-1]; R [I + k] = R [J + k]; k ++ );} return;} bool chk (INT mid, int N, int K) {int I, j; int CNT = 1; for (I = 1; I <= N; I ++) {If (height [I]> = mid) {CNT ++; If (CNT = k) return true;} else CNT = 1 ;} return false;} Char STR [maxn]; int main () {int N; int t; scanf ("% d", & T); While (t --) {int I, j; scanf ("% s", STR); int m = 0; n = strlen (STR); for (I = 0; STR [I]; I ++) {R [I] = STR [I]; M = max (M, (INT) STR [I]);} R [N] = 0; da (R, SA, n + 1, m + 1); calheight (R, SA, n); int ans = N-sa [1]; for (I = 2; I <= N; I ++) {// cout <SA [I] <Endl; ans + = N-sa [I]-height [I];} printf ("% d \ n", ANS);} return 0 ;}