[板子]后缀数组

 1 #include<bits/stdc++.h>
 2 #define N 10000010*2
 3 using namespace std;
 4 char s[N];
 5 int n;
 6 int sa[N],rk[N],height[N],t1[N],t2[N],c[N];
 7 int a[N];
 8 void get_sa(int n,int m){
 9     int *x=t1,*y=t2;
10     for(int i=1;i<=m;++i)c[i]=0;
11     for(int i=1;i<=n;++i)c[x[i]=a[i]]++;
12     for(int i=1;i<=m;++i)c[i]+=c[i-1];
13     for(int i=n;i>=1;--i)sa[c[x[i]]--]=i;
14     for(int k=1;k<=n;k<<=1){
15         int p=0;
16         for(int i=n-k+1;i<=n;++i)y[++p]=i;
17         for(int i=1;i<=n;++i)if(sa[i]>k)y[++p]=sa[i]-k;
18         for(int i=1;i<=m;++i)c[i]=0;
19         for(int i=1;i<=n;++i)c[x[y[i]]]++;
20         for(int i=1;i<=m;++i)c[i]+=c[i-1];
21         for(int i=n;i>=1;--i)sa[c[x[y[i]]]--]=y[i];
22         swap(x,y);
23         p=1;x[sa[1]]=1;
24         for(int i=2;i<=n;++i)
25             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p;
26         if(p==n)break;
27         m=p;
28     }
29     for(int i=1;i<=n;++i)rk[sa[i]]=i;
30     int f=0;
31     for(int i=1;i<=n;++i){
32         int j=sa[rk[i]-1];
33         if(f)f--;
34         while(i+f<=n&&j+f<=n&&s[j+f]==s[i+f])f++;
35         height[rk[i]]=f;
36     }
37 }
38 int main(){
39     scanf("%s",s+1);n=strlen(s+1);
40     for(int i=1;i<=n;++i)a[i]=s[i];
41     get_sa(n,150);
42     for(int i=1;i<=n;++i)
43         printf("%d%c",sa[i],i==n?'\n':' ');
44     return 0;
45 }

 

posted @ 2019-08-02 14:08  _xuefeng  阅读(34)  评论(0编辑  收藏  举报