后缀数组模板题。
花了半天时间去理解基于倍增和基数排序的后缀数组,理解之后,不用看模板直接开敲,一发AC,挺舒服的。
我是看<<算法竞赛入门经典训练指南>>这本书的,思路讲得挺好的,就是代码注释有点少,不利于理解。
加上这篇博客代码的注释就正好啦:​​后缀数组 最详细讲解​​ 我的代码没写注释,怕误导别人。

详细请看代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn=1000000+100;

char ch[maxn];
int sa[maxn],c[maxn],x[maxn],y[maxn];
int n,m;

void getSa(){

for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<n;i++) c[x[i]=ch[i]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=0;i<n;i++) sa[--c[x[i]]]=i;
for(int k=1;k<=n;k<<=1){

int num=0;
for(int i=n-k;i<n;i++) y[num++]=i;
for(int i=0;i<n;i++) if(sa[i]>=k) y[num++]=sa[i]-k;

for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<n;i++) c[x[y[i]]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];

swap(x,y);
int start=0;
x[sa[0]]=start++;
for(int i=1;i<n;i++) x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?start-1:start++;
if(start>=n) break;
m=start;
}
}

int main(){

scanf("%s",ch);
n=strlen(ch);
m=123;
getSa();
for(int i=0;i<n;i++) printf("%d%c",sa[i]+1,i==n-1?'\n':' ');
}