后缀数组

Posted vscoder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了后缀数组相关的知识,希望对你有一定的参考价值。

#include<cstdio>
#include<cstring>
#include<algorithm>

const int maxn=555555;

int n,m;
char s[maxn];
int sa[maxn],tp[maxn];
int rank[maxn],tong[maxn];

void qsort()
{
    for(int i=0;i<=m;i++)
        tong[i]=0;
    for(int i=1;i<=n;i++)
        tong[rank[i]]++;
    for(int i=0;i<=m;i++)
        tong[i]+=tong[i-1];
    for(int i=n;i>=1;i--)
        sa[tong[rank[tp[i]]]--]=tp[i];
}

void get_sa()
{
    m=127;
    for(int i=1;i<=n;i++)
    {
        rank[i]=s[i];
        tp[i]=i;
    }
    qsort();
    for(int w=1,p;p<n;m=p,w<<=1)
    {
        p=0;
        for(int i=1;i<=w;i++)
            tp[++p]=n-w+i;
        for(int i=1;i<=n;i++)
            if(sa[i]>w)
                tp[++p]=sa[i]-w;
        qsort();
        std::swap(rank,tp);
        rank[sa[1]]=p=1;
        for(int i=2;i<=n;i++)
            rank[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w])?p:++p;
    }
}

int rak[maxn];
int height[maxn];

void get_he()
{
    int k=0;
    for(int i=1;i<=n;i++)
        rak[sa[i]]=i;
    for(int i=1;i<=n;i++)
    {
        if(rak[i]==1) continue;
        if(k) k--;
        int j=sa[rak[i]-1];
        while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++;
        height[rak[i]]=k;
    }
}

int lg[maxn];
int st[maxn][22];

void build_st()
{
    lg[1]=0;
    for(int i=2;i<=n;i++)
        lg[i]=lg[i>>1]+1;
    for(int i=1;i<=n;i++)
        st[i][0]=height[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;(i+(1<<j)-1)<=n;i++)
            st[i][j]=std::min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}

void pre_solve()
{
    get_sa();
    get_he();
    build_st();
}

int get_lcp(int a,int b)
{
    a=rak[a],b=rak[b];
    if(a>b) std::swap(a,b);
    a++;
    int k=lg[b-a+1];
    return std::min(st[a][k],st[b-(1<<k)+1][k]);
}

int main()
{

}

 

以上是关于后缀数组的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段—— 数组的响应式方法

VSCode自定义代码片段10—— 数组的响应式方法

Sublime Text3自定义代码片段

后缀数组代码详解

●后缀数组○十三个例题

初学后缀数组记录(然而并不是很会。。&&很水。。)