zoukankan      html  css  js  c++  java
  • SA


    后缀数组 Suffix Array


    $M$ : 当前需要排序的集合大小

    $rank[i]$ : 当前以第 $i$ 位开头的后缀的排名,第一关键字
    $sa[i]$ : 第 $i$ 名的后缀的开头位置
    $tmp[i]$ : 第二关键字的排名为 $i$ 的后缀开头位置
    $tax[i]$ : 计数桶,集合内某元素出现次数

    void rsort() {
        for (int i = 1; i <= M; i++) tax[i] = 0;
        for (int i = 1; i <= N; i++) tax[rak[i]]++;
        for (int i = 2; i <= M; i++) tax[i] += tax[i - 1];
        for (int i = N; i >= 1; i--) sa[tax[rak[tmp[i]]]--] = tmp[i];
        //按第二关键字从大到小枚举后缀再标记,当第一关键字相同时,第二关键字大的后缀排在后面
    }
    
    
    void init() {
        for (int i = 1; i <= N; i++) rak[i] = s[i] - '0' + 1, tmp[i] = i;
        M = 75;
        rsort();
        for (int len = 1, p = 0; p < N; M = p, len <<= 1) {
            // p == N 时退出, 因为只要所有后缀排名互不相同时就已排序完毕,再排下去不会改变结果,可提前退出
            num = 0;
            for (int i = N - len + 1; i <= N; i++) tmp[++num] = i;
            for (int i = 1; i <= N; i++) if (sa[i] > len) tmp[++num] = sa[i] - len;
            rsort();
            swap(tmp, rak);
            rak[sa[1]] = p = 1;
            for (int i = 2; i <= N; i++) rak[sa[i]] = (tmp[sa[i]] == tmp[sa[i - 1]] && tmp[sa[i] + len] == tmp[sa[i - 1] + len] ? p : ++p);
        }
        int l = 0;
        for (int i = 1; i <= N; i++) {
            if (l) l--;
            int j = sa[rak[i] - 1];
            while (s[i + l] == s[j + l]) l++; 
            height[rak[i]] = l;
        }
    }
    View Code

    height数组性质证明

    $height[i]$ : 排名为 $i$ 的后缀与 $i - 1$ 的的 $lcp$(最长公共前缀)

    性质

    $$height[rak[i]] geq height[rak[i - 1]] - 1$$

    证明

    当$height[i - 1] geq 1$时

    设 $rak[k] = rak[i - 1] - 1$, 则有 $rak[k + 1] leq rak[i] - 1$

    $lcp(suffix[rak[i]], suffix[rak[i] - 1]) geq lcp(suffix[rak[i]], suffix[rak[k + 1]])$

    $lcp(suffix[rak[i]], suffix[rak[i] - 1]) geq lcp(suffix[rak[i - 1]], suffix[rak[k]]) - 1$

    $lcp(suffix[rak[i]], suffix[rak[i] - 1]) geq lcp(suffix[rak[i - 1]], suffix[rak[i - 1] - 1]) - 1$

  • 相关阅读:
    3.1.3、控制结构
    3.1.2、变量
    3.1.1、渲染模板
    3.1、Jinja2模板引擎
    第3章 模板
    2.6、Flask扩展
    2.5.4、响应
    2.5.3、请求钩子
    2.5.2、请求调度
    2.5.1、程序和请求上下文
  • 原文地址:https://www.cnblogs.com/Urushibara-Ruka/p/13124452.html
Copyright © 2011-2022 走看看