• 后缀数组


    留坑待填

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 20005;
    struct SA {
        int A[N], rank[N], sa[N], n, sum[N], height[N];
        struct radix_ele {
            int id;
            int k[2];
            radix_ele(){}
            radix_ele(int a, int b, int c) { id = a, k[0] = b, k[1] = c; }
        } RE[N], RT[N];
        void radix_sort()
        {
            for (int y = 1; y >= 0; y--) {
                memset(sum, 0, sizeof sum);
                for (int i = 1; i <= n; i++) sum[RE[i].k[y]]++;
                for (int i = 1; i < N; i++) sum[i] += sum[i-1];
                for (int i = n; i >= 1; i--) RT[sum[RE[i].k[y]]--] = RE[i];
                // 注意这里要逆序,关键字相同按原顺序
                for (int i = 1; i <= n; i++) RE[i] = RT[i];
            } // 通过前缀和计算位置,进行基数排序
            for (int i = 1; i <= n; i++) {
                rank[RE[i].id] = rank[RE[i-1].id];
                if (RE[i].k[0] != RE[i-1].k[0] || RE[i].k[1] != RE[i-1].k[1])
                    rank[RE[i].id]++;
            } // 计算rank,只有和前一个不同时才+1
        }
        void calc_sa()
        {
            for (int i = 1; i <= n; i++) RE[i] = radix_ele(i, A[i], 0);
            radix_sort();
            for (int k = 1; k < n; k <<= 1) {
                for (int i = 1; i <= n; i++) RE[i] = radix_ele(i, rank[i], i+k<=n?rank[i+k]:0);
                radix_sort();
            }
            for (int i = 1; i <= n; i++) sa[rank[i]] = i;
        }
        void calc_height()
        {
            int h = 0;
            for (int i = 1; i <= n; i++) {
                if (rank[i] == 1) h = 0;
                else {
                    int k = sa[rank[i]-1];
                    if (--h < 0) h = 0;
                    while (A[i+h] == A[k+h]) h++;
                }
                height[rank[i]] = h;
            }
        }
        void init()
        {
            calc_sa();
            calc_height();
        }
    } SA;
    int main()
    {
        scanf("%d", &SA.n);
        for (int i = 1; i <= SA.n; i++)
            scanf("%d", &SA.A[i]);
        SA.init();
        puts("--SA--");
        for (int i = 1; i <= SA.n; i++)
            cout << SA.sa[i] << ' ';
        puts("
    --RANK--");
        for (int i = 1; i <= SA.n; i++)
            cout << SA.rank[i] << " ";
        puts("
    --HEIGHT--");
        for (int i = 1; i <= SA.n; i++)
            cout << SA.height[i] << " ";
        return 0;
    }
  • 相关阅读:
    WinMain函数的修饰符WINAPI的含义
    java字节码指令集简介
    vs2010里面的ipch文件和.sdf文件是什么
    java查看class字节码文件
    从汇编看c++的extern关键字
    highcharts系列教程
    highcharts的文档介绍(英文)
    关于firebug中行号和源文件不一致的问题
    ios中的流状态的定义
    highcharts翻译系列
  • 原文地址:https://www.cnblogs.com/ljt12138/p/6684347.html
Copyright © 2020-2023  润新知