【洛谷 P3809】 【后缀数组】【模板】后缀排序
标题
解题思路
嗯。。。这是道模板题
雾里看花状态,咱就给点注释吧
我看的是这篇题解
代码
#include<iostream>
#include<cstdio>
using namespace std;
string s;
int n,m=1000;
int z[1001000],w[1000100],c[1000100],sa[1001000],wa[1000100],wb[1000100];
bool cmp(int *r,int xx,int yy,int k)
{
return (r[xx]==r[yy]&&r[xx+k]==r[yy+k]);
}
void work()
{
int j=1,p,d,*x=wa,*y=wb;
for (int i=0;i<n;i++) z[x[i]=c[i]]++;
for (int i=1;i<m;i++) z[i]+=z[i-1];
for (int i=n-1;i>=0;i--) sa[--z[x[i]]]=i; //单个字母排一次
while(1)
{
p=0,d=1;
for (int i=n-j;i<n;i++) y[p++]=i; //没有第二关键字放在最前面
for (int i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j; //位置大于j的才有第二关键字
for (int i=0;i<m;i++) z[i]=0;
for (int i=0;i<n;i++) w[i]=x[y[i]],z[w[i]]++; //取相应的第一关键字,然后排序
for (int i=1;i<m;i++) z[i]+=z[i-1];
for (int i=n-1;i>=0;i--) sa[--z[w[i]]]=y[i]; //取排名
swap(x,y);
x[sa[0]]=0;
for (int i=1;i<n;i++) //如果相同取一样的排名
if (cmp(y,sa[i-1],sa[i],j))
x[sa[i]]=d-1;
else x[sa[i]]=d++;
m=d;
if (d==n)
{
for (int i=0;i<n;i++)
printf("%d ",sa[i]+1);
return;
}
j*=2; //倍增
}
}
int main()
{
cin>>s;
n=s.size();
for (int i=0;i<n;i++)
c[i]=s[i]-'0'+1;
work();
return 0;
}