今天沒事幹,學了sa(其實是模擬賽掛了)。
引用資料:
2023年國家集訓隊**
洛谷**273期我們記 \(sa_i\) 為排名為 \(i\) 的字尾的開始位置。\(rk_i\) 為開始位置為 \(i\) 的字尾的排名。
我們採用基數排序,因為這樣在排序第一關鍵字的時候,第二關鍵字順序相對正確。(舉例子就是21和12排序,因為你的程式不知道什麼時候停止,如果從高到低一位一位排序,結果是12 21
,但是從低到高一位一位排序,結果是21 12
)
所以我們同時採用先排序第二關鍵字,再排序第一關鍵字。
然後就按 \(2^i\) 位直接多次基數排序。
先初始化
for (ll i = 0; i < n; i++) buc[rk[i] = ss[i]]++;
for (ll i = 1; i <= m; i++) buc[i] += buc[i-1];
for (ll i = n-1; i >= 0; i--) sa[--buc[rk[i]]] = i;
然後我們可以發現,對此時第二關鍵字排序的結果可以直接知道,那麼我們只用考慮排序這次的第一關鍵字了。
for (ll k = 1; k < n; k <<= 1)
void sa()
}
字尾陣列(SA)學習記錄
乙隻只會字尾自動機卻不會字尾陣列的弱雞做了一下hdu 1403,結果sam被卡記憶體了,然後學習了一下sa。以下兩道題都是求lcs,區別在於字串長度。hdu 1403 1 include 2 include 3 include 4 include 5 define rank rank 6using ...
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 長度的已經比完了...