Algorithm:
Concatenate the string in reverse order after the first string, and then obtain the longest public prefix ..
# Include <stdio. h> # include <stdlib. h> # include <string. h> # include <iostream> # include <vector> # include <string> # include <math. h> # include <map> # include <set> # include <algorithm> using namespace STD; # define maxn 10010int SA [maxn], rank [maxn], sum [maxn], height [maxn]; int wa [maxn], WB [maxn], wx [maxn], wsum [maxn]; char STR [maxn]; int DP [1010] [20];/* rmq: DP [I] [J] = max (DP [I] [J-1], DP [I + 2 ^ (J-1)] [J-1]) DP [I] [0] = A [I ]; Maximum range [I, j] int L = lg (J-I + 1) return max (DP [I] [L], DP [J + 1-2 ^ L] [l]); * // pre-processed height array void pre (int n) {for (INT I = 0; I <= N; I ++) DP [I] [0] = height [I]; int L = (INT) log2 (n); For (Int J = 1; j <= L; j ++) {for (INT I = 1; I <= n + 1-(1 <j); I ++) DP [I] [J] = min (DP [I] [J-1], DP [I + (1 <(J-1)] [J-1]);} int get_min (int A, int B) {int L = (INT) log2 (B-A + 1); Return min (DP [a] [L], DP [B + 1 -(1 <L)] [l]);} // compare whether the string is equal to int CMP (int * r, int A, int B, int L) {return (R [a] = R [B] & R [A + L] = R [B + L]);} // calculate the SA array void get_sa (char * r, int * Sa, int N, int m) using the multiplication algorithm. // R is a string, sa array, and N is the string length, M is the maximum value of the string {int I, j, P, * x = wa, * Y = WB, * t; for (I = 0; I <m; I ++) sum [I] = 0; // when the length of a pair is 1, the suffix string is sorted for (I = 0; I <n; I ++) sum [x [I] = R [I] ++; // X is equivalent to rank, but not really rank for (I = 1; I <m; I ++) sum [I] + = sum [I-1]; For (I = n-1; I> = 0; I --) SA [-- sum [x [I] = I; // The length of the pair is 2, 4 ,... for (j = 1, P = 1; P <n & J <= N; j * = 2) {// sort the keyword y first, the sorted result is saved in the Y array, that is, the starting position of the suffix string 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; // then sort the key word X. Obtain the 1st key word X for (I = 0; I <N; I ++) WX [I] = x [Y [I]; for (I = 0; I <m; I ++) wsum [I] = 0; for (I = 0; I <n; I ++) wsum [wx [I] ++; For (I = 1; I <m; I ++) wsum [I] + = wsum [I-1]; for (I = n-1; I> = 0; I --) SA [-- wsum [wx [I] = Y [I]; // update x T = x, x = Y, y = T; for (X [SA [0] = 0, I = 1, P = 1; I <n; I ++) x [SA [I] = CMP (Y, sa [I-1], sa [I], j )? P-1: P ++;} // H [I] = height [rank [I], H [I]> = H [I-1]-1 void get_height (char * r, int N) {int I, j, k = 0; // SA [0] = Len is the zero 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 ++ );} int LCP (int A, int B) {int x = rank [a]; int y = rank [B]; If (x> Y) Swap (x, y ); X + = 1; return get_min (x, y);} // calculate the longest return string int get_huiwen (int q, Int & P, int Len) {int num = 0, ans1, ans2; For (INT I = 0; I <q; I ++) {ans1 = LCP (I, len-I); ans2 = LCP (I, len-I-1); If (ans1 * 2> num) {num = ans1 * 2; P = I-ans1;} If (ans2 * 2-1> num ){ Num = ans2 * 2-1; P = I-ans2 + 1;} return num;} int main () {int A, B, n, m, Q; while (scanf ("% s", STR )! = EOF) {int Len = strlen (STR); STR [Len] = '$'; q = Len; For (INT I = Len + 1, k = 1; k <= Len; I ++, K ++) STR [I] = STR [Len-K]; Len * = 2; STR [Len + 1] = '#'; STR [Len + 2] = 0; memset (WA, 0, sizeof (WA); memset (WB, 0, sizeof (WB); memset (SA, 0, sizeof (SA); memset (height, 0, sizeof (height); get_sa (STR, SA, len + 1,255); get_height (STR, Len); Pre (LEN); int p = 0; int x = get_huiwen (Q, P, Len + 1 ); for (INT I = P; I <= P + X-1; I ++) printf ("% C", STR [I]); puts ("");}}