Http://poj.org/problem? Id = 3450
I did this during my vacation. At that time, I used KMP. This time I used a suffix array.
Concatenate n strings and separate them with different characters that do not appear in the input string. Separate each character in The New String according to the region of the atomic string and mark it with the LOC array.
The length of a binary common substring. Check whether the height values of N consecutive Suffixes in the adjacent suffixes are greater than the enumerated values and belong to n different strings.
Code:
# Include <cstdio> // The longest public substring.
# Include <cstring>
# Define max (A, B) A> B? A: B
Const int maxn = 805000;
Int wa [maxn], WB [maxn], WV [maxn], WS [maxn], rank [maxn], height [maxn], sa [maxn], s [maxn], Loc [maxn];
Char STR [201], ANS [201];
Bool vis [4001];
Int m;
Int CMP (int * r, int A, int B, int L ){
Return R [a] = R [B] & R [A + L] = R [B + L];
}
Void da (int * r, int N, int m ){
Int I, j, P, * x = wa, * Y = WB, * t;
For (I = 0; I <m; I ++) WS [I] = 0;
For (I = 0; I <n; I ++) WS [x [I] = R [I] ++;
For (I = 1; I <m; I ++) WS [I] + = ws [I-1];
For (I = n-1; I> = 0; I --) SA [-- ws [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 ++) 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 --) SA [-- ws [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;
}
Void calheight (int * r, int N ){
Int I, j, k = 0;
For (I = 1; I <= N; I ++) rank [SA [I] = I; // obtain the rank value O (N)
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 check (INT mid, int Len ){
Int COUNT = 0;
Memset (VIS, false, sizeof (VIS ));
For (INT I = 2; I <= Len; I ++ ){
If (height [I] <mid ){
Memset (VIS, false, sizeof (VIS ));
Count = 0;
Continue;
}
If (! Vis [loc [SA [I-1]) vis [loc [SA [I-1] = true, Count ++;
If (! Vis [loc [SA [I]) vis [loc [SA [I] = true, Count ++;
If (COUNT = m ){
For (Int J = 0; j <mid; j ++)
Ans [J] = s [SA [I] + J] + 'a'-1;
Ans [Mid] = '\ 0 ';
Return 1;
}
}
Return 0;
}
Int main (){
Int t, n, I, j, Max, temp, flag;
While (~ Scanf ("% d", & M ){
N = 0, temp = 30, flag = 0;
For (I = 1; I <= m; I ++ ){
Scanf ("% s", STR );
For (j = 0; j <strlen (STR); j ++ ){
Loc [N] = I;
S [n ++] = STR [J]-'A' + 1;
}
Loc [N] = temp;
S [n ++] = temp ++;
}
S [N] = 0;
Da (S, N + 1, temp );
Calheight (S, N );
Int left = 0, Right = strlen (STR), mid;
While (Right> = left ){
Mid = (right + Left)/2;
If (check (MID, n )){
Left = Mid + 1;
Flag = mid;
}
Else
Right = mid-1;
}
If (FLAG) printf ("% s \ n", ANS );
Else printf ("identity lost \ n ");
}
Return 0 ;}