The hight array is the soul!
Multiplication Algorithm O (nlgn)
# Define maxn 100010int wa [maxn], WB [maxn], WV [maxn], and WSS [maxn]; // The ws of the thesis template conflicts with the keywords in G ++! 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. [instructions]: The string starts with 0 subscript. The algorithm must add 0 at the end, and the SA value is 0 ~ N-1, the value of rank is 1 ~ N, the subscript of height starts from 0, but height [0] = 0, height [1] = 0, height [2] indicates the longest public prefix with the previous one. */Void da (int * r, int * Sa, int N, int m) {// n must be added with 1. m is the character range of 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;} int rmq [maxn]; int mm [maxn]; int best [20] [maxn]; void initrmq (int n) {int I, j, A, B; for (Mm [0] =-1, I = 1; I <= N; I ++) mm [I] = (I & (I-1 )) = 0 )? Mm [I-1] + 1: Mm [I-1]; for (I = 1; I <= N; I ++) Best [0] [I] = I; for (I = 1; I <= mm [N]; I ++) for (j = 1; j <= n + 1-(1 <I ); j ++) {A = Best [I-1] [J]; B = Best [I-1] [J + (1 <(I-1)]; if (rmq [a] <rmq [B]) Best [I] [J] = A; else best [I] [J] = B;} return ;} int askrmq (int A, int B) {int t; t = mm [B-A + 1]; B-= (1 <t)-1; A = Best [T] [a]; B = Best [T] [B]; return rmq [a] <rmq [B]? A: B;} int LCP (int A, int B) {// The Longest Common preorder int t; A = rank [a]; B = rank [B]; if (A> B) {T = A; A = B; B = T;} return (height [askrmq (a + 1, B)]);}
DC3 algorithm O (N)
# Define maxn 1000003 # define f (x) (X)/3 + (x) % 3 = 1? 0: Tb) # define g (x) <TB? (X) * 3 + 1 :( (x)-TB) * 3 + 2) int wa [maxn], WB [maxn], WV [maxn], WS [maxn]; int C0 (int * r, int A, int B) {return R [a] = R [B] & R [A + 1] = R [B + 1] & R [A + 2] = R [B + 2];} int C12 (int K, int * r, int A, int B) {If (k = 2) return R [a] <R [B] | r [a] = R [B] & C12 (1, R, A + 1, B + 1 ); else return R [a] <R [B] | r [a] = R [B] & WV [A + 1] <WV [B + 1];} void sort (int * r, int * a, int * B, int N, int m) {int I; for (I = 0; I <n; I ++) WV [I] = R [A [I]; for (I = 0; I <m; I ++) WS [I] = 0; for (I = 0; I <N; I ++) WS [wv [I] ++; for (I = 1; I <m; I ++) WS [I] + = ws [I-1]; for (I = n-1; I> = 0; I --) B [-- ws [wv [I] = A [I]; return;} void DC3 (int * r, int * Sa, int N, int m) {int I, j, * rn = R + N, * San = SA + N, TA = 0, TB = (n + 1)/3, TBC = 0, P; R [N] = R [n + 1] = 0; for (I = 0; I <n; I ++) if (I % 3! = 0) wa [TBC ++] = I; sort (R + 2, WA, WB, TBC, m); sort (R + 1, WB, WA, TBC, m); sort (R, WA, WB, TBC, m); For (P = 1, RN [F (WB [0])] = 0, I = 1; I <TBC; I ++) Rn [F (WB [I])] = C0 (R, WB [I-1], WB [I])? P-1: P ++; If (P <TBC) DC3 (RN, San, TBC, P); else for (I = 0; I <TBC; I ++) san [Rn [I] = I; for (I = 0; I <TBC; I ++) if (San [I] <TB) WB [ta ++] = San [I] * 3; if (N % 3 = 1) WB [ta ++] = n-1; sort (R, WB, WA, ta, m); for (I = 0; I <TBC; I ++) WV [WB [I] = g (San [I])] = I; for (I = 0, j = 0, P = 0; I <TA & J <TBC; P ++) sa [p] = C12 (WB [J] % 3, R, wa [I], WB [J])? Wa [I ++]: WB [J ++]; for (; I <ta; P ++) SA [p] = wa [I ++]; (; j <TBC; P ++) SA [p] = WB [J ++]; return;} int rank [maxn], height [maxn]; void calheight (int * r, int * Sa, int N) {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 ;} int rmq [maxn]; int mm [maxn]; int best [20] [maxn]; void initrmq (int n) {int I, j, A, B; for (Mm [0] =-1, I = 1; I <= N; I ++) mm [I] = (I & (I-1 )) = 0 )? Mm [I-1] + 1: Mm [I-1]; for (I = 1; I <= N; I ++) Best [0] [I] = I; for (I = 1; I <= mm [N]; I ++) for (j = 1; j <= n + 1-(1 <I ); j ++) {A = Best [I-1] [J]; B = Best [I-1] [J + (1 <(I-1)]; if (rmq [a] <rmq [B]) Best [I] [J] = A; else best [I] [J] = B;} return ;} int askrmq (int A, int B) {int t; t = mm [B-A + 1]; B-= (1 <t)-1; A = Best [T] [a]; B = Best [T] [B]; return rmq [a] <rmq [B]? A: B;} int LCP (int A, int B) {int t; A = rank [a]; B = rank [B]; If (A> B) {T = A; A = B; B = T;} return (height [askrmq (a + 1, B)]);} int R [maxn * 3], sa [maxn * 3]; // 3 times space!