标签:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN = 1e4+7; struct SuffixArr { int tempx[MAXN], tempy[MAXN], text[MAXN]; int rank[MAXN], sa[MAXN], height[MAXN], sum[MAXN]; int *x, *y, N, MaxId; void GetText(char s[]) { N = strlen(s)*2+2, MaxId = 200; x = tempx, y = tempy; int i; for(i=0; s[i]; i++) { text[i] = text[N-i-2] = x[i] = x[N-i-2] = (int)s[i]; y[i] = i, y[N-i-2] = N-i-2; } text[i] = x[i] = 1, y[i] = i; text[N-1] = x[N-1] = 0, y[N-1] = N-1; /// debug(); } bool cmp(int i, int len) { if(sa[i]+len > N || sa[i-1]+len > N) return false; if(y[sa[i]] != y[sa[i-1]] || y[sa[i]+len] != y[sa[i-1]+len]) return false; return true; } void baseSort() { for(int i=0; i<MaxId; i++) sum[i] = 0; for(int i=0; i<N; i++) sum[ x[ y[i] ] ] += 1; for(int i=1; i<MaxId; i++) sum[i] += sum[i-1]; for(int i=N-1; i>=0; i--) sa[ --sum[ x[ y[i] ] ] ] = y[i]; } void GetSa() { baseSort(); for(int len=1; len<=N; len<<=1) { int id = 0; for(int i=N-len; i<N; i++) y[id++] = i; for(int i=0; i<N; i++)if(sa[i] >= len) y[id++] = sa[i] - len; baseSort(); swap(x, y); x[ sa[0] ] = id = 0; for(int i=1; i<N; i++) { if(cmp(i, len) == true) x[ sa[i] ] = id; else x[ sa[i] ] = ++id; } MaxId = id + 1; if(MaxId >= N)break; } } void GetHeight() { for(int i=0; i<N; i++) rank[ sa[i] ] = i; for(int k=0, i=0; i<N; i++) { if(!rank[i]) { height[0] = k = 0; continue; } if(k)k--; int pre = sa[ rank[i]-1 ]; while(text[i+k] == text[pre+k]) k++; height[rank[i]] = k; } /// debug(); } void debug() { for(int i=0; i<N; i++) printf("%d: %d\n", i, height[i]); } }; struct segmentTree { int val[MAXN], L[MAXN], R[MAXN]; void Build(int root, int l, int r, int p[]) { L[root] = l, R[root] = r; if(l == r) { val[root] = p[l]; return ; } int Mid = (l+r)>>1; Build(root<<1, l, Mid, p); Build(root<<1|1, Mid+1, r, p); val[root] = min(val[root<<1], val[root<<1|1]); } int Query(int root, int u, int v) { if(L[root] == u && R[root] == v) return val[root]; int Mid = (L[root]+R[root]) / 2; if(v <= Mid) return Query(root<<1, u, v); else if(u > Mid) return Query(root<<1|1, u, v); else return min(Query(root<<1, u, Mid), Query(root<<1|1, Mid+1, v)); } }; SuffixArr suf; segmentTree seg; char s[MAXN]; int main() { while(scanf("%s", s) != EOF) { int len = strlen(s)+1; suf.GetText(s); suf.GetSa(); suf.GetHeight(); seg.Build(1, 0, suf.N-1, suf.height); int MaxLen=1, k=0, x, y; for(int i=0; i<len-1; i++) for(int j=0; j<2; j++) { if(j==0) x = suf.rank[len*2-i-2]; else x = suf.rank[len*2-i-1]; if(i==0 && j)continue; y = suf.rank[i+1]; if(x > y)swap(x, y); int m = seg.Query(1, x+1, y) * 2 + j; if(MaxLen < m) { MaxLen = m; k = i-(m+j)/2+1; } } s[k+MaxLen] = 0; printf("%s\n", s+k); } return 0; }
Palindrome - URAL - 1297(求回文串)
标签:
原文地址:http://www.cnblogs.com/liuxin13/p/4782866.html