洛谷P3809 【模板】后缀排序
这里,仅仅介绍一下如何进行字符串的后缀排序
$STL$ 中的 $sort$ ? 想得美 $!$
由于 $sort$ 函数在比较字符串大小时会将字符串的每一个字
符逐一比较,整体复杂度便是 $O(n^2logn)$ .
我们需要一个更快的方法来对后缀排序.
由于不太好讲,我就不讲啦QAQ...
Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 1000013
using namespace std;
char str[maxn];
int a[maxn],rk[maxn],sa[maxn],tp[maxn],tax[maxn],n,m;
void read(){
scanf("%s",str);
n=strlen(str);
for(int i=0;i<n;++i) a[i+1]=str[i];
}
void qsort(){
for(int i=0;i<=m;++i) tax[i]=0;
for(int i=1;i<=n;++i) ++tax[rk[tp[i]]];
for(int i=1;i<=m;++i) tax[i]+=tax[i-1];
for(int i=n;i>=1;--i) sa[tax[rk[tp[i]]]--]=tp[i];
}
void suffix(){
for(int i=1;i<=n;++i) rk[i]=a[i],tp[i]=i;
qsort();
for(int k=1;k<=n;k<<=1){
int num=0;
for(int i=n-k+1;i<=n;++i)tp[++num]=i;
for(int i=1;i<=n;++i) if(sa[i]>k) tp[++num]=sa[i]-k;
qsort();
swap(rk,tp);
rk[sa[1]]=1;
num=1;
for(int i=2;i<=n;++i)
rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+k]&&tp[sa[i]+k]==tp[sa[i-1]+k])?num:++num;
if(num==n) break;
m=num;
}
return;
}
int main(){
//setIO("input");
read();
m=122;
suffix();
for(int i=1;i<=n;++i) printf("%d ",sa[i]);
return 0;
}