TYVJ1860 后缀数组
就是模板而已。
然而最后两个点倍增TLE,听说非要DC3算法才能过?
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int mxn=300010; 8 int sa[mxn],ht[mxn]; 9 int wa[mxn],wb[mxn],wv[mxn]; 10 int cnt[mxn],rk[mxn]; 11 bool cmp(int *r,int a,int b,int k){ 12 return (r[a]==r[b] && r[a+k]==r[b+k]); 13 } 14 void SA(int *r,int n,int m){ 15 int i,j; 16 for(i=0;i<m;i++)cnt[i]=0; 17 for(i=0;i<n;i++)cnt[wa[i]=r[i]]++; 18 for(i=1;i<m;i++)cnt[i]+=cnt[i-1]; 19 for(i=n-1;i>=0;i--)sa[--cnt[wa[i]]]=i; 20 int p=1; 21 for(j=1;p<n;j<<=1,m=p){ 22 for(p=0,i=n-j;i<n;i++)wb[p++]=i; 23 for(i=0;i<n;i++)if(sa[i]>=j)wb[p++]=sa[i]-j; 24 for(i=0;i<n;i++)wv[i]=wa[wb[i]]; 25 for(i=0;i<m;i++)cnt[i]=0; 26 for(i=0;i<n;i++)++cnt[wv[i]]; 27 for(i=1;i<m;i++)cnt[i]+=cnt[i-1]; 28 for(i=n-1;i>=0;i--)sa[--cnt[wv[i]]]=wb[i]; 29 swap(wa,wb); 30 wa[sa[0]]=0; 31 for(p=1,i=1;i<n;i++){ 32 wa[sa[i]]=cmp(wb,sa[i-1],sa[i],j)?p-1:p++; 33 } 34 } 35 return; 36 } 37 void cal_height(int *s,int n){ 38 int i,j,k=0; 39 for(i=1;i<=n;i++)rk[sa[i]]=i; 40 for(i=0;i<n;i++){ 41 if(k)k--; 42 j=sa[rk[i]-1]; 43 while(s[i+k]==s[j+k])k++; 44 ht[rk[i]]=k; 45 } 46 return; 47 } 48 char s[mxn]; 49 int r[mxn]; 50 int main(){ 51 int i,j; 52 scanf("%s",&s); 53 int len=strlen(s); 54 for(i=0;i<len;i++)r[i]=s[i]-'a'+1; 55 r[len]=0; 56 SA(r,len+1,30); 57 for(i=1;i<=len;i++)printf("%d ",sa[i]+1); 58 printf("\n"); 59 cal_height(r,len); 60 for(i=1;i<=len;i++)printf("%d ",ht[i]); 61 printf("\n"); 62 return 0; 63 }
本文为博主原创文章,转载请注明出处。