sa(模板)

这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

const int N=100001;
char s[N];
int n,len,a[N],b[N],cc[N],sa[N],hei[N],rak[N];

int cmp(int *y,int a,int b,int k)
{
    int ra1=y[a];
    int rb1=y[b];
    int ra2=a+k>=len? -1:y[a+k];
    int rb2=b+k>=len? -1:y[b+k];
    return ra1==rb1&&ra2==rb2;  //ra1==rb1&&ra2==rb2 
}

void make_sa()
{
    int i,j,k,m,p;
    int *x=a,*y=b,*t;
    m=26;
    for (i=0;i<len;i++) cc[i]=0;
    for (i=0;i<len;i++) ++cc[x[i]=s[i]-'a'];
    for (i=1;i<m;i++) cc[i]+=cc[i-1];
    for (i=len-1;i>=0;i--) sa[--cc[x[i]]]=i;
    for (k=1;k<=len;k<<=1)
    {
        p=0;
        for (i=len-k;i<len;i++) y[p++]=i;
        for (i=0;i<len;i++) if (sa[i]>=k) y[p++]=sa[i]-k;
        for (i=0;i<m;i++) cc[i]=0;
        for (i=0;i<len;i++) ++cc[x[y[i]]];
        for (i=1;i<m;i++) cc[i]+=cc[i-1];
        for (i=len-1;i>=1;i--) sa[--cc[x[y[i]]]]=y[i];
        t=x;x=y;y=t;
        x[sa[0]]=0; p=1;
        for (i=1;i<len;i++)
           x[sa[i]]=cmp(y,sa[i-1],sa[i],k)? p-1:p++;  //p-i:p++
        if (p>=len) break;  //
        m=p;
    }
}

void make_hei()
{
    int i,k=0;
    hei[0]=0;
    for (i=0;i<len;i++) rak[sa[i]]=i;
    for (i=0;i<len;i++)
    {
        if (!rak[i]) continue;
        int j=sa[rak[i]-1];
        if (k) k--;
        while (s[i+k]==s[j+k]) k++;
        hei[rak[i]]=k;
    }
    return;
}

int main()
{
    scanf("%s",&s);
    len=strlen(s);
    make_sa();
    make_hei();
    return 0;
}
原文地址:https://www.cnblogs.com/wutongtong3117/p/7673577.html