• 后缀数组 (核心:所有的字串都是某一个后缀的前缀)


    各个数组含义

    sa[] 名次-》位置

    _rank[] 位置-》名次

    tp [] 第二关键字  名次-》位置

    height[]  两个排名相邻后缀最长公共前缀

    性质1 两个后缀(i,j)的最大公共前缀=min (height[_rank[i]+1].....height[_rank[j]] ) (假设排名_rank[i]<_rank[j])

    性质2 h[i]>=h[i-1]-1 (h[i] i位置的后缀数组和它前一名的最长公共前缀)

    void resort () {//基数排序
        for (int i=0;i<=m;i++) tax[i]=0;
        for (int i=1;i<=n;i++) tax[ _rank[i] ]++;
        for (int i=1;i<=m;i++) tax[i]+=tax[i-1];
        for (int i=n;i>=1;i--) sa[tax[_rank[tp[i]]]--]=tp[i];
    }
    void build_sa() {
        for (int i=1;i<=n;i++) {
            _rank[i]=a[i];
            tp[i]=i;
        }
        m=27; resort();// 初始化
        for (int w=1,p=1,i;p<n;w+=w,m=p) {
            // 第二关键字排序
            for (p=0,i=n-w+1;i<=n;i++) tp[++p]=i;
            for (i=1;i<=n;i++) if (sa[i]>w) tp[++p]=sa[i]-w;
            //  第一关键字排序 
            resort();
            // 根据sa[]求_rank[] 
            swap(_rank,tp);  _rank[sa[1]]=p=1;
            for (i=2;i<=n;i++) {
                if (tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w]) 
              _rank[sa[i]]=p; else
              _rank[sa[i]]=(++p); } } return ; } void build_height() { int k=0;// height数组 for (int i=1;i<=n;i++) { if (k) k--; int j=sa[_rank[i]-1]; while (str[i+k]==str[j+k]) k++; height[_rank[i]]=k; } return ; }
    抓住青春的尾巴。。。
  • 相关阅读:
    初賽
    SA
    高斯-约旦消元法
    AC自动机
    KMP
    关于scanf
    网络流
    常用SQL语句
    Java开发中的23种设计模式详解(转)
    generatorConfig.xml
  • 原文地址:https://www.cnblogs.com/xidian-mao/p/8400629.html
Copyright © 2020-2023  润新知