洛谷 3809 【模板】后缀排序——后缀数组

题目:https://www.luogu.org/problemnew/show/P3809

因为那个判断:tp[ sa[ i ] + k ] == tp[  sa[ i-1 ] + k ] ,tp[ ] 岂不是得开两倍?又有 swap( rk , tp ) ,rk[ ] 岂不是也得开两倍?

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+5;
int n,sa[N],rk[N<<1],tx[N],tp[N<<1];
char a[N];
void Rsort(int nm)
{
  for(int i=1;i<=nm;i++)tx[i]=0;
  for(int i=1;i<=n;i++)tx[rk[tp[i]]]++;
  for(int i=2;i<=nm;i++)tx[i]+=tx[i-1];
  for(int i=n;i;i--)sa[tx[rk[tp[i]]]--]=tp[i];
}
void work()
{
  int nm=0;
  for(int i=1;i<=n;i++)tp[i]=i;
  for(int i=1;i<=n;i++)if(!tx[(int)a[i]])nm++,tx[(int)a[i]]=1;
  for(int i=1;i<=122;i++)tx[i]+=tx[i-1];
  for(int i=1;i<=n;i++)rk[i]=tx[(int)a[i]];
  nm=tx[122];  Rsort(nm);
  for(int k=1;k<=n;k<<=1)
    {
      int tot=0;
      for(int i=n-k+1;i<=n;i++)tp[++tot]=i;
      for(int i=1;i<=n;i++)
    if(sa[i]>k)tp[++tot]=sa[i]-k;//pos of rnki -- tp:sorted by snd
      Rsort(nm);
      swap(rk,tp);nm=1;rk[sa[1]]=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-1]+k])?nm:++nm;//rk[sa[i]]
      if(nm==n)break;
    }
}
int main()
{
  scanf("%s",a+1);n=strlen(a+1);
  work();
  for(int i=1;i<=n;i++)printf("%d ",sa[i]);puts("");
  return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/10074986.html