• P3809 【模板】后缀排序


    P3809 【模板】后缀排序

    从这学的

    后缀数组sa[i]就表示排名为i的后缀的起始位置

    x[i]是第i个元素的第一关键字

    y[i]表示第二关键字排名为i的数,在第一关键字中的位置

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N 1000005
    #define rint register int
    int n,m,c[N],sa[N],x[N],y[N]; char s[N];
    void get_sa(){
        for(rint i=1;i<=n;++i) ++c[x[i]=s[i]];
        for(rint i=1;i<=m;++i) c[i]+=c[i-1];
        for(rint i=n;i>=1;--i) sa[c[x[i]]--]=i;
        for(rint k=1;k<=n;k<<=1){
            rint u=0;
            for(rint i=n-k+1;i<=n;++i) y[++u]=i;//逆序也没关系,因为都是没有
            for(rint i=1;i<=n;++i) if(sa[i]>k) y[++u]=sa[i]-k;
            for(rint i=1;i<=m;++i) c[i]=0;
            for(rint i=1;i<=n;++i) ++c[x[i]];
            for(rint i=1;i<=m;++i) c[i]+=c[i-1];
            for(rint i=n;i>=1;--i) sa[c[x[y[i]]]--]=y[i],y[i]=0;//按第二关键字排序
            swap(x,y); x[sa[1]]=1; u=1;
            for(rint i=2;i<=n;++i)
                x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?u:++u;
            if(u==n){break;} m=u;
        }
    }
    int main(){
        scanf("%s",s+1); n=strlen(s+1),m=125;
        get_sa();
        for(rint i=1;i<=n;++i) printf("%d ",sa[i]);
        return 0;
    }

    sa求最长公共前缀

    void get_height() //求最长公共前缀
    {
        for(rint i=1;i<=n;i++) rk[sa[i]]=i;
        rint k=0;
        for(rint i=1;i<=n;i++)
        {
            if(rk[i]==1) continue;
            if(k) --k;
            rint j=sa[rk[i]-1];
            while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) ++k;
            height[rk[i]]=k;
        }
    }
  • 相关阅读:
    @media screen针对不同移动设备-响应式设计
    闭包的一些例子
    es6 新关键字const
    es6 新关键字let
    Unity 多屏(分屏)显示,Muti_Display
    小米手机常用操作
    Charles使用笔记
    AKKA学习笔记
    Gatling-Session
    Scala学习笔记-6-其他
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10639316.html
Copyright © 2020-2023  润新知