分别输出排名为$$i$$的后缀的第一个字符在原串中的位置,排名为$$i$$和排名为$$i+1$$的后缀的最长公共前缀的长度。

#include <bits/stdc++.h>
#define rep(i,f,t) for(int i=f; i<t; i++)
using namespace std;
const int MAXN = 100000;
int n;
char s[MAXN+10];
int sa[MAXN+10], Rank[MAXN+10], top[MAXN+10], tmp[MAXN+10], height[MAXN+10];
void build_sa()
{
    int m = 130;
    int *x=Rank, *y = tmp;
    rep(i,0,m) top[i]=0;
    rep(i,0,n) top[x[i]=s[i]]++;
    rep(i,1,m) top[i]+=top[i-1];
    for(int i=n-1; i>=0; i--) sa[--top[x[i]]] = i;
    for(int k=1; k<=n; k<<=1)
    {
        int p=0;
        rep(i,n-k,n) y[p++]=i;
        rep(i,0,n) if(sa[i]>=k) y[p++]=sa[i]-k;

        rep(i,0,m) top[i]=0;
        rep(i,0,n) top[x[i]]++;
        rep(i,1,m) top[i]+=top[i-1];
        for(int i=n-1; i>=0; i--) sa[--top[x[y[i]]]] = y[i];

        swap(x, y);

        p=1; x[sa[0]]=0;
        rep(i,1,n)
            x[sa[i]] = (y[sa[i]]==y[sa[i-1]] and y[sa[i]+k]==y[sa[i-1]+k]) ? p-1 : p++;
        m = p;
        if (p >= n) break;
    }
}

void build_height()
{
    int k=0;
    rep(i,0,n) Rank[sa[i]]=i;
    rep(i,0,n)
    {
        if (k) k--;
        if (Rank[i]-1<0) {k=0;continue;}
        int j=sa[Rank[i]-1];
        while(i+k < n and j+k < n and s[i+k]==s[j+k]) k++;
        height[Rank[i]]=k;
    }
}

int main()
{
   scanf("%s", s);
   n = (int)strlen(s)+1;
   build_sa();
   build_height();
   rep(i,1,n) printf(i==1?"%d":" %d", sa[i]+1); puts("");
   rep(i,2,n) printf(i==2?"%d":" %d", height[i]); puts("");
}

results matching ""

    No results matching ""