模板奉上

int rank[maxn],height[maxn];
void calheight(int *r,int *sa,int n)
{
int i,j,k=;
for(i=;i<=n;i++) rank[sa[i]]=i;
for(i=;i<n;height[rank[i++]]=k)
  for(k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k];k++) //求h[i] = height[rank[i]];
      ;
return;
}

概念:

(1)height 数组:定义height[i]=suffix(SA[i-1])和suffix(SA[i])的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀的长度 。

(2)h[i]=height[rank[i]],也就是suffix(i)和排序后在它前一名的后缀的最长公共前缀的长度。

(3)函数lcp(u,v)=max{i|u=v},也就是从头开始顺次比较u和v的对应字符,对应字符持续相等的最大位置,称为这两个字符串u,v的最长公共前缀的长度。

(4)LCP(i,j):对正整数i,j 定义LCP(i,j)=lcp(Suffix(SA[i]),Suffix(SA[j]),其中i,j 均为1至n的整数。LCP(i,j)也就是后缀数组中第i个和第j个后缀的最长公共前缀的长度。

性质

(1)LCP(i,j)=min{height[k]|i+1≤k≤j},也就是说,计算LCP(i,j)等同于询问一维数组height[] 中下标在i+1 到j 范围内的所有元素的最小值。

(2)对于i>1 且Rank[i]>1,一定有h[i]≥h[i-1]-1。(这条性质要好好理解!)

  证明:设suffix(k)是排在suffix(i-1)前一名的后缀,它们的最长公共前缀是h[i-1]。

那么suffix(k+1)将排在suffix(i)的前面(这里要求h[i-1]>1,如果h[i-1]≤1,原式显然成立)并且suffix(k+1)和suffix(i)的最长公共前缀是h[i-1]-1,

所以suffix(i)和在它前一名的后缀的最长公共前缀至少是h[i-1]-1。

按照h[1],h[2],……,h[n]的顺序计算,并利用h 数组的性质,时间复杂度可以降为O(n)。

  即:

   rank[i-1] = q-1 suffix(k):        rabaa

   rank[i-1] = q    suffix(i-1):    racadabrabaa         h[i-1] = 2;

   ......

   rank[k-1] = p-1   suffix(k-1):     abaa

   rank[i] = p          suffix(i):       acadabrabaa         h[i] = 1 (h[i] >= h[i-1]-1 = 1;)

 

计算数组h[]

可以令i从1循环到n(此循环中i的意义为suffix(i))按照如下方法依次算出h[i]:

  若 Rank[i]=1,则h[i]=0。字符比较次数为0。

  若i=1或者h[i-1]≤1,则直接将Suffix(i)和Suffix(Rank[i]-1)从第一个字符开始依次比较直到有字符不相同,由此计算出h[i]。字符比较次数为h[i]+1,不超过h[i]-h[i-1]+2。

  否则,说明i>1,Rank[i]>1,h[i-1]>1,根据性质2,Suffix(i)和Suffix(Rank[i]-1)至少有前h[i-1]-1 个字符是相同的,于是字符比较可以从h[i-1]开始,直到某个字符不相同,由此计算出h[i]。字符比较次数为h[i]-h[i-1]+2。

  可求得最后算法复杂度为O(n)。

【后缀数组之height数组】的更多相关文章

  1. 【POJ2774】Long Long Message(后缀数组求Height数组)

    点此看题面 大致题意: 求两个字符串中最长公共子串的长度. 关于后缀数组 关于\(Height\)数组的概念以及如何用后缀数组求\(Height\)数组详见这篇博客:后缀数组入门(二)--Height ...

  2. 后缀数组入门(二)——Height数组与LCP

    前言 看这篇博客前,先去了解一下后缀数组的基本操作吧:后缀数组入门(一)--后缀排序. 这篇博客的内容,主要建立于后缀排序的基础之上,进一步研究一个\(Height\)数组以及如何求\(LCP\). ...

  3. 关于后缀数组的倍增算法和height数组

    自己看着大牛的论文学了一下后缀数组,看了好久好久,想了好久好久才懂了一点点皮毛TAT 然后就去刷传说中的后缀数组神题,poj3693是进化版的,需要那个相同情况下字典序最小,搞这个搞了超久的说. 先简 ...

  4. 后缀数组的一些性质----height数组

    height数组:定义 height[i] = suffix[i-1] 和 suffix[i] 的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀.那么对于 j 和 k 不妨设 Rank[j] & ...

  5. BZOJ2251 [2010Beijing Wc]外星联络 后缀数组 + Height数组

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in", "r", stdin ...

  6. 洛谷P2408 不同子串个数 后缀数组 + Height数组

    ## 题目描述: 给你一个长为 $N$ $(N<=10^5)$ 的字符串,求不同的子串的个数我们定义两个子串不同,当且仅当有这两个子串长度不一样 或者长度一样且有任意一位不一样.子串的定义:原字 ...

  7. luogu P2852 [USACO06DEC]牛奶模式Milk Patterns 后缀数组 + Height数组 + 二分答案 + 扫描

    后缀数组有一个十分有趣的性质: $height[rk[i]] >= height[rk[i-1]] - 1$    Code: #include <bits/stdc++.h> #d ...

  8. Java后缀数组-求sa数组

    后缀数组的一些基本概念请自行百度,简单来说后缀数组就是一个字符串所有后缀大小排序后的一个集合,然后我们根据后缀数组的一些性质就可以实现各种需求. public class MySuffixArrayT ...

  9. 【后缀数组之SA数组】【真难懂啊】

    基本上一搜后缀数组网上的模板都是<后缀数组——处理字符串的有力工具>这一篇的注释,O(nlogn)的复杂度确实很强大,但对于初次接触(比如窝)的人来说理解起来也着实有些困难(比如窝就活活好 ...

随机推荐

  1. Hadoop HA 机制学习

    一.Hadoop 系统架构 1.1 Hadoop1.x和Hadoop2.x 架构 在介绍HA之前,我们先来看下Hadoop的系统架构,这对于理解HA是至关重要的.Hadoop 1.x之前,其官方架构如 ...

  2. Apache Spark介绍及集群搭建

    简介 Spark是一个针对于大规模数据处理的统一分析引擎.其处理速度比MapReduce快很多.其特征有: 1.速度快 spark比mapreduce在内存中快100x,比mapreduce在磁盘中快 ...

  3. linux: sort排序数据 grep搜索数据

    sort 1.sort filename 输出排序后的结果,默认按字符大小排序 2.-n 按数字排序(如果内容是数字的话) 3.-M 按月份排序(如果是三字符简写月份的话) 下面这个例子非常实用: g ...

  4. Nginx 相关介绍(Nginx是什么?能干嘛?个人觉得写得比较好的文章,转载过来)

    Nginx的产生 没有听过Nginx?那么一定听过它的"同行"Apache吧!Nginx同Apache一样都是一种WEB服务器.基于REST架构风格,以统一资源描述符(Unifor ...

  5. unity3d xml序列化

    using UnityEngine; using System.Collections; using System.Xml; using System.Xml.Serialization; using ...

  6. JavaScript中的一些小技巧

    js 数字操作:1.1 取整:取整有很多方法如: parseInt(a,10); Math.floor(a); a>>0; ~~a; a|0; 前面2种是经常用到的,后面3种算是比较偏的, ...

  7. Oracle-属性查询

    1. 查询表的部分字段属性 select t.*, c.comments from user_tab_columns t, user_col_comments c where t.table_name ...

  8. jQuery中deferred对象的使用(一)

    在jquery1.5之后的版本中,加入了一个deferred对象,也就是延迟对象,用来处理未来某一时间点发生的回调函数.同时,还改写了ajax方法,现在的ajax方法返回的是一个deferred对象. ...

  9. [C++] Returning values by reference in C++

    A C++ program can be made easier to read and maintain by using references rather than pointers. A C+ ...

  10. mosquitto配置通过ssl通信

    mosquitto配置通过ssl通信 摘自https://www.cnblogs.com/stin/p/9258211.html 注意项: For openssl >= 1.0.1 the va ...