Topic links
Test instructions: The longest palindrome substring of the given string
Analysis: The procedure is to construct a new string that is the original string + invert the original string (so as to facilitate the longest prefix of a palindrome suffix), that is, news = S + ' $ ' + revs, enumerate the center position of the palindrome string, rmq ask LCP = min (height[rank[l]+1] to He IGHT[RANK[R]), note that the RMQ incoming parameter is preferably the suffix position, because their order in the tree is unknown, and the left side is +1.
#include <cstdio> #include <algorithm> #include <cstring>const int N = 1e3 + 10;const int D = 21;char S[n] ; int sa[n<<1], t[n<<1], t2[n<<1], c[n<<1], N;int rank[n<<1], Height[n<<1];int Dp[N <<1][d];void da (char *s, int m = n) {int I, *x = t, *y = t2; 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 (int k=1; k<=n; k<<=1) {int p = 0; for (i=n-k; i<n; ++i) y[p++] = i; for (i=0; i<n; ++i) if (Sa[i] >= k) y[p++] = sa[i]-K; for (i=0; i<m; ++i) c[i] = 0; for (i=0; i<n; ++i) c[x[y[i]]]++; for (i=0; i<m; ++i) c[i] + = c[i-1]; for (i=n-1; i>=0;-i) sa[--c[x[y[i]] [] = y[i]; Std::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]+k] = = Y[sa[i]+k]? P-1: p++; } if (P >= N) break; m = p; }//height[i] = LCP (S[sa[i-1]], s[sa[i]); Int J, k = 0; for (i=0; i<n; ++i) rank[sa[i]] = i; for (i=0; i<n; ++i) {if (k) k--; Int j = Sa[rank[i]-1]; while (s[i+k] = = S[j+k]) k++; Height[rank[i]] = k; }}int query_rmq (int l, int r) {L = Rank[l]; r = Rank[r]; if (L > R) {std::swap (L, R); } l++; int k = 0; while (1<< (k+1) <= r-l + 1) k++; Return Std::min (Dp[l][k], dp[r-(1<<k) +1][k]);} void init_rmq (int *height) {//memset (DP, 0, sizeof (DP)); for (int i=0; i<=n; ++i) {dp[i][0] = Height[i]; } for (int j=1; (1<<J) <=n; ++J) {for (int i=0; i+ (1<<j) <=n; ++i) {Dp[i][j] = Std::min (Dp[i][j-1], dp[i+ (1<< (j-1)) ][j-1]); }}}int Run (char *s) {int len = strlen (s); n = len; s[n++] = ' $ '; for (int i=len-1; i>=0;-I.) { s[n++] = s[i]; } s[n++] = ' + '; Da (s); INIT_RMQ (height); int ret = 0; for (int i=0; i<len; ++i) {int L = QUERY_RMQ (i, n-i-2);//ODD ret = Std::max (ret, 2 * l-1); L = QUERY_RMQ (i, n-i-1); even ret = Std::max (ret, 2 * l); } return ret;} int main () {int cas = 0; while (scanf ("%s", s) = = 1) {if (strcmp (S, "END") = = 0) {break; } printf ("Case%d:%d\n", ++cas, run (s)); } return 0;}
URAL 1297 topic No difference, the data size is small, but also output palindrome string.
Core code
int best = 0;from = 0; to = 1;for (int i=0; i<len; ++i) { int l = QUERY_RMQ (i, n-i-1); if (Best < 2 * l-1) {from = i-l + 1, to = i + L; Best = 2 * L-1; } L = QUERY_RMQ (i, n-i); if (Best < 2 * L) {from = i-l; to = i + L; Best = 2 * l; }}
Suffix array POJ 3974 palindrome && URAL 1297 palindrome