Ural 1297 Palindrome (后缀数组)
2015-11-02 19:06
483 查看
题目地址:Ural 1297
后缀数组模板题。把字符串倒过来接到字符串后面,并在中间加一个从未出现的字符。然后用后缀数组就可以了。
代码如下:
后缀数组模板题。把字符串倒过来接到字符串后面,并在中间加一个从未出现的字符。然后用后缀数组就可以了。
代码如下:
#include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h> #include <string> #include <time.h> using namespace std; #define LL long long #define pi acos(-1.0) #pragma comment(linker, "/STACK:1024000000") const int mod=9901; const int INF=0x3f3f3f3f; const double eqs=1e-9; const int MAXN=2000+10; char st[MAXN]; int wa[MAXN], wb[MAXN], wv[MAXN], ws1[MAXN], s[MAXN]; int sa[MAXN], rk[MAXN], height[MAXN]; int cmp(int *r, int a, int b, int l) { return r[a]==r[b]&&r[a+l]==r[b+l]; } void getsa(int *r, int *sa, int n, int m) { int i, j, p, *x=wa, *y=wb, *t; for(i=0;i<m;i++) ws1[i]=0; for(i=0;i<n;i++) ws1[x[i]=r[i]]++; for(i=1;i<m;i++) ws1[i]+=ws1[i-1]; for(i=n-1;i>=0;i--) sa[--ws1[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++) ws1[i]=0; for(i=0;i<n;i++) ws1[wv[i]]++; for(i=1;i<m;i++) ws1[i]+=ws1[i-1]; for(i=n-1;i>=0;i--) sa[--ws1[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=0;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } } void Calheight(int *r, int n) { int i, j, k=0; for(i=1;i<=n;i++) rk[sa[i]]=i; for(i=0;i<n;height[rk[i++]]=k){ for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++) ; } } int pan(char c) { if(c>='a'&&c<='z') return c-'a'+1; return c-'A'+27; } int main() { int len, i, j, max1, pos, tmp, n; while(scanf("%s",st)!=EOF){ len=strlen(st); n=0; for(i=0;i<len;i++){ s[n++]=st[i]; } s[n++]=200; for(i=len-1;i>=0;i--){ s[n++]=st[i]; } s =0; getsa(s,sa,n+1,300); Calheight(s,n); max1=1; pos=0; for(i=1;i<n;i++){ tmp=height[i]; if(max1<tmp){ if(sa[i-1]<len&&sa[i]>len&&sa[i-1]+tmp==n-sa[i]){ max1=tmp; pos=sa[i-1]; } else if(sa[i]<len&&sa[i-1]>len&&sa[i]+tmp==n-sa[i-1]){ max1=tmp; pos=sa[i]; } } else if(max1==tmp){ if(sa[i-1]<len&&sa[i]>len&&sa[i-1]+tmp==n-sa[i]){ if(pos>sa[i-1]) pos=sa[i-1]; } else if(sa[i]<len&&sa[i-1]>len&&sa[i]+tmp==n-sa[i-1]){ if(pos>sa[i]) pos=sa[i]; } } } for(i=pos;i<pos+max1;i++){ printf("%c",st[i]); } puts(""); } return 0; }