「模板」 后缀数组
勉强理解吧,思路明白了但是代码很麻烦啊。
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1000010;
char s[MAXN];
int n,m=128,SA[MAXN],x[MAXN],y[MAXN],cnt[MAXN];
void Print(int *a,int n)
{
for(int i=0;i<n;++i)
printf("%d ",a[i]);
putchar('
');
}
void GetSA(void)
{
for(int i=0;i<n;++i)
++cnt[x[i]=s[i]];
for(int i=1;i<m;++i)
cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;--i)
SA[--cnt[x[i]]]=i;
for(int k=1,p;k<=n,p<n/*继续倍增SA也不会改变时退出*/;k<<=1,m=p/*下次基数排序的最大值*/)
{
p=0;//利用SA排序第二关键字
for(int i=n-k;i<n;++i)
y[p++]=i;
for(int i=0;i<n;++i)
if(SA[i]>=k)
y[p++]=SA[i]-k;
//排第一关键字
memset(cnt,0,sizeof cnt);
for(int i=0;i<n;++i)
++cnt[x[y[i]]];
for(int i=1;i<m;++i)
cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;--i)
SA[--cnt[x[y[i]]]]=y[i];
//根据SA和y数组计算新的X数组
swap(x,y);
p=1,x[SA[0]]=0;
for(int i=1;i<n;++i)
x[SA[i]]=y[SA[i-1]]==y[SA[i]] && y[SA[i-1]+k]==y[SA[i]+k] ? p-1 : p++;
}
}
int main(int argc,char *argv[])
{
scanf("%s",s);
n=strlen(s);
GetSA();
for(int i=0;i<n;++i)
printf("%d ",SA[i]+1);
putchar('
');
return 0;
}
谢谢阅读