SA 字尾陣列

2022-03-20 08:02:20 字數 1969 閱讀 4583

首先一定要確定\(sa\)是個什麼東西

\(sa[i]\)表示的是排名為\(i\)的字尾是哪乙個

至於字尾\(i\)的排名是多少,那個是\(rank[i]\)

當然啦最最最難懂的就是基數排序

要是不用基數排序,每次對於乙個二元組直接\(sort\)一下

這樣的複雜度是\(o(nlog^2)\)

對於二元組的基數排序應該是這樣做的:

首先把所有元素按照最後一維丟到依次對應的桶裡面

然後順次取出

再按照第一維依次丟入

再順次取出

這樣就可以排序啦

先把**丟出來

bool cmp(int i,int j,int k)

void getsa()

}

首先,第一次做\(k=0\)時

相當於每個字尾的第二維都是一樣的

所以,直接按照第一維(也就是自己的值)

進行一次基數排序

接下來每次基數排序都要利用到上一次的值

還記得吧,基數排序是先按照第二維從小往大拍

那麼,我們就先把第二維的順序搞出來

首先最小的一定就是沒有第二維的東西

所以我們先把這些數直接丟進陣列裡面

接下來就是有第二維的東西啦

第\(i\)位的第二維是啥?\(rank[i+k]\)

所以,從小到達列舉\(sa\),這樣保證第二維從小往大

那麼,只要\(sa[i]>k\)

就證明它是乙個東西的第二維

所以,把\(sa[i]-k\)丟到陣列裡面去就好啦

這樣的話,按照第二維就拍好啦

再來依次按照第一維丟到桶裡面去

做一遍基數排序就好啦

這樣就能夠求出\(sa\)啦

看起來很簡單誒。。

只是陣列不要搞混了

一定搞清楚每個陣列是幹啥的

比如我的**

\(sa\)是字尾陣列,\(sa[i]\)表示排名為\(i\)的串是哪乙個

\(rank\)相當於排名,\(rank[i]\)表示第\(i\)個串的排名

\(x,y\)兩個陣列是記錄順序的

分別記錄第一維和第二維的排序的順序

\(t\)是桶

這樣我們就很愉快的求出了\(sa\)

還有乙個陣列\(height\)

\(height[i]\)表示串\(sa[i]\)與\(sa[i-1]\)的最長公共字首的長度

比如說,現在要求字尾\(i\)與\(j\)的最長公共字首

那就只需要求\(min(height[i]),i \in [rank[i]+1,rank[j]]\)

因為已經按照字典序排好序啦

\(height\)顯然可以暴力求

但是太不優美

我們有\(height[rank[i]]>=height[rank[i-1]]-1\)

證明(來自\(hihocoder\))

設\(suffix(k)\)是排在\(suffix(i-1)\)前一名的字尾,

則它們的最長公共字首是\(height[rank[i-1]]\)

那麼\(suffix(k+1)\)將排在\(suffix(i)\)的前面(這裡要求\(height[rank[i-1]]>1\),如果\(height[rank[i-1]]≤1\),原式顯然成立)

並且\(suffix(k+1)\)和\(suffix(i)\)的最長公共字首是\(height[rank[i-1]]-1\),

所以\(suffix(i)\)和在它前一名的字尾的最長公共字首至少是\(height[rank[i-1]]-1\)

那麼,我們按照\(rank\)的順序來求\(height\)就行啦

for(int i=1;i<=n;++i)rank[sa[i]]=i;

for(int i=1,j=0;i<=n;++i)

我現在也不是很熟

以後多做點題我再接著補

SA 字尾陣列

首先一定要確定sa 是個什麼東西 sa i 表示的是排名為 i 的字尾是哪乙個 至於字尾 i的排名是多少,那個是ra nk i 當然啦 最最最難懂的就是基數排序 要是不用基數排序,每次對於乙個二元組直接so rt一下 這樣的複雜度是o nlog 2 對於二元組的基數排序應該是這樣做的 首先把所有元素...

字尾陣列SA

給定乙個字串s,按字典序排序s的所有子串 鬼知道什麼思想,好像沒有什麼思想。哦,想起來了,是倍增。考慮最簡單的字尾間o n o n 比較和快排o nlog n o n logn 總複雜度o n2lo gn o n 2log n 考慮優化字串間的比較,用倍增的思想,假設k 2 k 2 長度的已經比完了...

字尾陣列SA

原理 其本質就是把字串的所有字尾進行排序。用普通排序需要o nlogn 但是字串比較和數字比較不同,所以實際需要o n nlogn 為了讓這個過程快一點,所以有了倍增演算法,o nlogn 和dc3演算法,o n 倍增演算法比較簡單,也比較好寫,具體可以參考這個大佬的部落格。dc3演算法複雜一點,但...