• 洛谷P3809 后缀数组模板


    把题读清楚,题中的输入是包括数字、大写字母和小写字母的。
    初始化排名的时候可以把字符的ascii值作为排位,因为排名是可以并列的。但是最后的后缀排名是不可能并列的,因为每一个后缀的长度不一样。
    基数排序的时候,注意处理并列的情况。下面的代码是复旦大学的程序设计里面的代码,写的挺清晰的,想看的可以直接粘走。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=1e6+10;
    
    struct Node {
        int next,now;
    }d[maxn];
    
    int pos[maxn],c[maxn],SA[maxn],Rank[maxn],val[maxn][2],n;
    char s[maxn];
    
    void add_value(int u,int v,int i)
    {
        d[i].next=c[u];
        c[u]=i;
        d[i].now=v;
    }
    
    void radix_sort(int l,int r)
    {
        for (int k=1;k>=0;k--) {
            memset(c,0,sizeof(c));
            for (int i=r;i>=l;i--) {
                add_value(val[pos[i]][k],pos[i],i);
            }
            int t=0;
            for (int i=0;i<maxn;i++) {
                for (int j=c[i];j;j=d[j].next) {
                    pos[++t]=d[j].now;
                }
            }
        }
        int t=0;
        for (int i=1;i<=n;i++) {
            if (val[pos[i]][0]!=val[pos[i-1]][0]||val[pos[i]][1]!=val[pos[i-1]][1]) ++t;
            Rank[pos[i]]=t;
        }
    
    }
    
    void get_suffix_array()
    {
        int t=1;
        while (t/2<=n) {
            for (int i=1;i<=n;i++) {
                val[i][0]=Rank[i];
                val[i][1]=(i+t/2<=n)?Rank[i+t/2]:0;
                pos[i]=i;
            }
            
            // for (int i=1;i<=n;i++) {
            //     printf("val: %d %d
    ",val[i][0],val[i][1]);
            // }
    
            radix_sort(1,n);
            t*=2;
    
            // for (int i=1;i<=n;i++) {
            //     printf("%d ",Rank[i]);
            // }
            // puts("");
            // printf("%d%t",t);
    
        }
        for (int i=1;i<=n;i++) {
            SA[Rank[i]]=i;
        }
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        scanf("%s",s+1);
        n=strlen(s+1);
        for (int i=1;i<n+1;i++) {
            Rank[i]=(int)s[i];
            // printf("%d ",Rank[i]);
        }
        get_suffix_array();
        for (int i=1;i<=n;i++) {
            printf("%d",SA[i]);
            if (i<n) putchar(' ');
        }
        return 0;
    }
    
  • 相关阅读:
    高二下期末考试
    LG月赛.7
    CF1187E
    P5440 【XR-2】奇迹
    P1084 疫情控制
    P1083 借教室
    P2680 运输计划
    P3128 [USACO15DEC]最大流Max Flow
    博弈入门
    HDU 1907
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/12328858.html
Copyright © 2020-2023  润新知