Inputthe input consists of a single line, which contains a string of Latin alphabet letters (no other characters would appe AR in the string). String length would not exceed characters. Outputthe longest substring with the mentioned property. If There is several such strings you should output the first of them. Sample
input |
Output |
Thesampletextthatcouldbereadedthesameinbothordersarozaupalanalapuazora |
Arozaupalanalapuazora |
problem Author:Eugene Krokhalev
problem Source:IX Open Collegiate Programming Contest of the High School pupils (13.03.2004)
Tags:String algorithms() difficulty:97 Printable version Submit solution Discussion (61)
My Submissions All submissions (19277) all accepted submissions (5968)
Test instructions: Output maximum palindrome string
Idea: The base problem in the suffix array, exhaustive each bit, and then calculates the longest palindrome substring centered on this character. Note that there are two cases, one is the length of the palindrome substring is odd, the second is the length is even. Both cases can be converted to the longest common prefix of a suffix and a suffix that is written in reverse. This is done by writing the entire string in turn behind the original string, separated by a special character. This turns the problem into the longest common prefix of a two suffix that asks for the new string. ST's RMQ or do not use the template, knock it yourself. The suffix array is O (N*logn), with the RMQ query first initialized after the complexity is O (n)
1297. palindromeg++ 4.9accepted0.031530 kb#include<cstdio> #include <iostream> #include <algorithm># include<cstring>using namespace std;; const INT Maxn=2010;int t1[maxn],t2[maxn],c[maxn];//The intermediate variable required for the SA array, does not need to be assigned//the string to be sorted in the S array, from s[0] to s[n-1], the length is n, and the maximum value is less than m,/ /except s[n-1] all S[i] is greater than the 0,r[n-1]=0//function ends after the result is placed in the SA array bool cmp (int *r,int a,int b,int l) {return r[a] = = R[b] && r[a+l] = = R[b+l];} void da (int str[],int sa[],int rank[],int height[],int n,int m) {n++;//Note int i, J, p, *x = t1, *y = t2; The first round of cardinality sorting, if the maximum value of S is large, can be changed to quick sort (change only the first round) for (i = 0;i < m;i++) C[i] = 0; for (i = 0;i < n;i++) C[x[i] = str[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 (j = 1;j <= N; J <<= 1) {p = 0; Directly using the SA array to sort the second keyword for (i = n-j; i < n; i++) y[p++] = i;//The second key is empty for the minimum for (i = 0; i < n; i++) if (sa[ I] >= j) y[p++] = sa[i]-J; So the array y holds the result sorted by the second keyword//cardinality sort first keyword for (i = 0; i < m; i++) c[i] = 0; for (i = 0; i < n; i++) c[x[y[i]]]++; for (i = 1; i < m;i++) C[i] + = c[i-1]; for (i = n-1; I >= 0;i--) sa[--c[x[y[i]]] = y[i]; Calculates a new x array of swaps based on the SA and X arrays;//small optimization p = 1; X[sa[0]] = 0; for (i = 1;i < n;i++) X[sa[i] = CMP (y,sa[i-1],sa[i],j)? p-1:p++; if (P >= N) break;//small optimization m = p;//The maximum value of the next cardinality order} int k = 0; n--;//Note for (i = 0;i <= n;i++) rank[sa[i]] = i; for (i = 0;i < n;i++) {if (k) k--; j = Sa[rank[i]-1]; while (str[i+k] = = Str[j+k]) k++; Height[rank[i]] = k; }}int rank[maxn],height[maxn];int rmq[maxn];int mm[maxn];int best[20][maxn];void initRMQ (int n) {mm[0]=-1; for (int i=1;i<=n;i++) mm[i]= (i& (i-1)) ==0? MM[I-1]+1:MM[I-1]; for (int i=1;i<=n;i++) best[0][i]=i; for (int i=1;i<=mm[n];i++) for (int j=1;j+ (1<<i) -1<=n;j++) {int a=best[i-1][j]; int b=best[i-1][j+ (1<< (i-1))]; if (rmq[a]<rmq[b]) best[i][j]=a; else best[i][j]=b; }}int askrmq (int a,int b) {int t=mm[b-a+1]; b= 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) {a= rank[a]; b= Rank[b]; Return height[askrmq (min (A, B) +1,max (A, b)]; Char str[maxn];int r[maxn];int sa[maxn];int Main () {while (~SCANF ("%s", str)) {int Len=strlen (str); int n=len*2+1; for (int i=0;i<len;i++) r[i]=str[i]; R[len]=1; for (int i=0;i<len;i++) r[i+len+1]=str[len-i-1]; r[n]=0; Da (r,sa,rank,height,n,130); for (int i=1;i<=n;i++) rmq[i] = Height[i]; INITRMQ (n); int st,maxn=-1; for (int i=0;i<len;i++) {int tmp; TMP=LCP (i,n-i); if (maxn<2*tmp) {maxn=2*tmp; st=i-tmp; } TMP=LCP (i,n-i-1); if (maxn<2*tmp-1) {maxn=2*tmp-1; st=i-tmp+1; }} str[st+maxn]=0; printf ("%s\n", str+st); } return 0;}
Finding palindrome string Manacher algorithm complexity is O (n) and programming difficulty is very small
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring>using namespace std;const int Maxn=1010;char ma[maxn*2];int mp[maxn*2];void manacher (char s[],int len) { int l=0; Ma[l++]= ' $ '; ma[l++]= ' # '; for (int i=0;i<len;i++) { ma[l++] = s[i]; ma[l++] = ' # '; } ma[l]=0; int mx=0,id=0; for (int i=1;i<l;i++) { Mp[i] = mx>i? min (mp[2*id-i],mx-i): 1; while (Ma[i+mp[i]]==ma[i-mp[i]]) mp[i]++; if (i+mp[i]>mx) { mx=i+mp[i]; id=i;}}} Char S[maxn];int main () { while (~scanf ("%s", s)) { int len=strlen (s); Manacher (S,len); int ans=0; int St; for (int i=0;i<2*len+2;i++) if (ans<mp[i]-1) { ans = mp[i]-1; St = (I-mp[i]) >>1; } s[st+ans]=0; printf ("%s\n", s+st); } return 0;}
URAL 1297. Palindrome (output longest palindrome substring--suffix array)