字尾陣列模板 LCP小證明

2021-10-05 17:34:52 字數 1373 閱讀 3917

複習了一遍字尾陣列:

關於lcp的證明:簡單的說下:

設p=min(height[k])       ilcp(i,j)=p,

顯然lcp(i,j)<=p(排名越相近,字首越可能相同)

假設lcp(i,j)= tp。

則字串sa[i]和字串sa[j]前tp位相同。

從sa[i]到sa[j]之間的字串一定是從sa[i]到sa[j] 字典序遞增變化。

則其會一點點從len[sa[i]]變化到tp+1位,知道變成sa[j],每一位變化跟前一位的lcp一定小於等於當前。

即p<=tp

又因為tp<=p;

則tp==p即

等式lcp(i,j)=min(height[k])       i成立!

另外:(小拓展)

lcp(i,j)其實就是lcp(i,i+1,i+2……,j)即連續l個字尾的lcp

#include#include#includeconst int maxn = 1e6 + 10;

using namespace std;

char s[maxn];

int n, m, rak[maxn], sa[maxn], tax[maxn], tp[maxn],height[maxn];

//tp[i] 第二關鍵字排名i的下標

//rak[i] 下標i的字尾的排名

//sa[i] 第一關鍵字排名i的下標。。最終是排名i的字尾的下標

//height[i] suffix(sa[i-1]) 和 suffix(sa[i]) 的最長公共字首長度

// suffix(i)開頭下標為i的字尾

//我們定義lcp(i,j)為suff(sa[i])與suff(sa[j])的最長公共字首

//h[i]:height[rak[i]],即i號字尾與它前一名的字尾的最長公共字首

//h[i]>=h[i-1]-1

//lcp(i,k)=min(lcp(i,j),lcp(j,k)) 對於任意1<=i<=j<=k<=n

//lcp(i,k)=min(lcp(j,j-1)) 對於任意1=x

依次列舉每一組,記錄下最大和最小長度,多sa[mx]?sa[mi]>=xsa[mx]?sa[mi]>=x那麼可以更新答案

本質不同的子串的數量

列舉每乙個字尾,第ii個字尾對答案的貢獻為len?sa[i]+1?height[i]

*/ void qsort()

void suffixsort()

//for (int i = 1; i <= n; i++)

//printf("%d ", sa[i]);

}void getheight()

}int main()

字尾陣列入門(二) Height陣列與LCP

看這篇部落格前,先去了解一下字尾陣列的基本操作吧 字尾陣列入門 一 字尾排序。這篇部落格的內容,主要建立於字尾排序的基礎之上,進一步研究乙個 height 陣列以及如何求 lcp lcp 即 longest common prefix 是最長公共字首的意思。而在字尾陣列中,lcp i,j 表示字尾 ...

字尾陣列 LCP(最長公共字首)

sa sa陣列儲存的是乙個1 n的全排列,儲存的是 將所有字尾按字典序排序後,串在原串中的位置。即有suffix sa i suffix sa i 1 rank rank陣列儲存的是 suffix i 在所有字尾中按字典序排序的 名次 總結 字尾陣列是 排第幾的是誰?名次陣列是 你排第幾?lcp i...

字尾陣列 模板

char s n 陣列的長度要為兩倍的 int n n全域性變數為字元陣列的長度的 int sa n 2 high n 2 rank n 2 tmp n 2 top n 2 void makesa void lcp int main gets s int len strlen s s len get...