http://acm.hdu.edu.cn/showproblem.php?pid=3518
后缀数组
View Code
1 //3518 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 int Max(int x,int y) {return x>y?x:y;} 7 int Min(int x,int y) {return x<y?x:y;} 8 const int L=1010; 9 char str[L]; 10 int r[L],wa[L],wb[L],ws[L]; 11 int sa[L],rank[L],high[L]; 12 bool cmp(int *r,int a,int b,int l) 13 { 14 return (r[a]==r[b]&&r[a+l]==r[b+l]); 15 } 16 void suffix(int *r,int n,int m) 17 { 18 int *x=wa,*y=wb; 19 for(int i=0;i<m;i++) ws[i]=0; 20 for(int i=0;i<n;i++) ws[x[i]=r[i]]++; 21 for(int i=1;i<m;i++) ws[i]+=ws[i-1]; 22 for(int i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; 23 for(int j=1,p=1;p<n;j<<=1,m=p) 24 { 25 p=0; 26 for(int i=n-j;i<n;i++) y[p++]=i; 27 for(int i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 28 for(int i=0;i<m;i++) ws[i]=0; 29 for(int i=0;i<n;i++) ws[x[y[i]]]++; 30 for(int i=1;i<m;i++) ws[i]+=ws[i-1]; 31 for(int i=n-1;i>=0;i--) sa[--ws[x[y[i]]]]=y[i]; 32 int *t=x; x=y; y=t; 33 p=1; 34 x[sa[0]]=0; 35 for(int i=1;i<n;i++) 36 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 37 } 38 for(int i=1;i<n;i++) rank[sa[i]]=i; 39 for(int i=0,k=0;i<n-1;i++) 40 { 41 if(k) k--; 42 int j=sa[rank[i]-1]; 43 while(r[i+k]==r[j+k]) k++; 44 high[rank[i]]=k; 45 } 46 } 47 int get(int l,int n) 48 { 49 int cnt=0,max=sa[1],min=sa[1]; 50 for(int i=2;i<n;i++) 51 if(high[i]>=l) 52 { 53 max=Max(max,sa[i]); 54 min=Min(min,sa[i]); 55 } 56 else 57 { 58 if(max-min>=l) cnt++; 59 max=min=sa[i]; 60 } 61 if(max-min>=l) cnt++; 62 return cnt; 63 } 64 int main() 65 { 66 while(scanf("%s",str),strcmp(str,"#")) 67 { 68 int len=strlen(str); 69 for(int i=0;str[i];i++) r[i]=str[i]-'a'+1; 70 r[len++]=0; 71 suffix(r,len,27); 72 int ans=0; 73 for(int i=1;i<=(len-1)/2;i++) ans+=get(i,len); 74 printf("%d\n",ans); 75 } 76 return 0; 77 }