后缀数组模板(倍增)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 char str[1000005];
 5 int x[1000005],y[1000005],u[1000005],v[1000005],r[1000005],o[1000005],m=256,n;
 6 
 7 int main(){
 8     scanf("%s",str+1);
 9     n=strlen(str+1);
10     
11     for(int i=1;i<=n;i++) u[str[i]]++;
12     for(int i=1;i<=m;i++) u[i]+=u[i-1];
13     for(int i=n;i>=1;i--) x[u[str[i]]--]=i;
14     r[x[1]]=1;
15     for(int i=2;i<=n;i++) r[x[i]]=r[x[i-1]]+((str[x[i]]-str[x[i-1]])?1:0);
16     
17     for(int l=1;r[x[n]]<n;l<<=1) {
18         memset(u,0,sizeof u);
19         memset(v,0,sizeof v);
20         memcpy(o,r,sizeof r);
21         for(int i=1;i<=n;i++) u[r[i]]++, v[(i+l<=n)?r[i+l]:0]++;
22         for(int i=1;i<=n;i++) u[i]+=u[i-1], v[i]+=v[i-1];
23         for(int i=n;i>=1;i--) y[v[(i+l<=n)?r[i+l]:0]--]=i;
24         for(int i=n;i>=1;i--) x[u[r[y[i]]]--]=y[i];
25         r[x[1]]=1;
26         for(int i=2;i<=n;i++) 
27             r[x[i]]=r[x[i-1]]+((o[x[i]] != o[x[i-1]])  ||  (((x[i]+l<=n)?o[x[i]+l]:0) != ((x[i-1]+l<=n)?o[x[i-1]+l]:0)));
28     }
29     for(int i=1;i<=n;i++) printf("%d ",x[i]);
30 }
原文地址:https://www.cnblogs.com/mollnn/p/8443118.html