BZOJ 1031 后缀数组
题解:
把原串直接接在后头,然后后缀数组本来就排序好了,正好用来求题目所需~
毛线的,nlogn的就是烦,还是nlog^2n的好写,,
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstdio> 6 7 #define N 220000 8 9 using namespace std; 10 11 char s[N]; 12 int rank[N],sa[N]; 13 int wa[N],wb[N],wc[N],wv[N]; 14 int p[N]; 15 16 inline bool cmp(int *r,int a,int b,int l) 17 { 18 return r[a]==r[b]&&r[a+l]==r[b+l]; 19 } 20 21 inline void da(char *r,int *sa,int n,int m) 22 { 23 int i,j,p,*x=wa,*y=wb,*t; 24 for(i=0;i<m;i++) wc[i]=0; 25 for(i=0;i<n;i++) wc[x[i]=r[i]]++; 26 for(i=1;i<m;i++) wc[i]+=wc[i-1]; 27 for(i=n-1;i>=0;i--) sa[--wc[x[i]]]=i; 28 for(j=1,p=1;p<n;j<<=1,m=p) 29 { 30 for(i=n-j,p=0;i<n;i++) y[p++]=i; 31 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 32 for(i=0;i<n;i++) wv[i]=x[y[i]]; 33 for(i=0;i<m;i++) wc[i]=0; 34 for(i=0;i<n;i++) wc[wv[i]]++; 35 for(i=1;i<m;i++) wc[i]+=wc[i-1]; 36 for(i=n-1;i>=0;i--) sa[--wc[wv[i]]]=y[i]; 37 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 38 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 39 } 40 } 41 42 inline void go() 43 { 44 scanf("%s",s); 45 int slen=strlen(s); 46 int n=slen*2; 47 for(int i=0;i<slen;i++) s[slen+i]=s[i]; 48 s[n-1]=0; 49 da(s,sa,n,300); 50 for(int i=0;i<n;i++) rank[sa[i]]=i; 51 for(int i=0;i<slen;i++) p[rank[i]]=s[i+slen-1]; 52 for(int i=0;i<n;i++) 53 if(p[i]) printf("%c",p[i]); 54 } 55 56 int main() 57 { 58 go(); 59 return 0; 60 }
没有人能阻止我前进的步伐,除了我自己!