颯颯颯颯颯颯颯颯颯颯
研究了好長時間....(誒好像莫比烏斯反演時也說過這句話)
1.2.
3.字尾陣列小結/#more
【概念】:(**裡很清楚了,這裡說自己的理解)
1. 字尾:字尾是指從某個位置i開始到結束的子串。suffix(i)=r[i..len(r)]
字尾i是從i開始的子串
2. 字尾陣列:字尾陣列 sa 是乙個一維陣列,它儲存1..n 的某個排列 sa[1],sa[2], ……,sa[n],並且保證suffix(sa[i]) < suffix(sa[i+1]),1 ≤ i < n。也就是將 s 的 n 個字尾從小到大進行排序之後把排好序的字尾的開頭位置順次放入sa 中。
字尾排序之後的結果
sa[i]是排名為i的字尾的起點下標(開始位置)
3. 名次陣列:名次陣列 rank[i] 儲存的是 suffix(i) 在所有字尾中從小到大排列的 「 名次 」 。
rank[i]是字尾i的名次(從i開始的子串 位置i的子串)
【倍增演算法】:
見**描述
一張圖,每個位置開始長度為j的排序,然後用兩個j組成2*j排序.........
【實現】:
排序使用計數排序,
n是字串長度,m是字元大小上限
a是要排序陣列 sa字尾陣列
c是計數排序用的
r為「第一關鍵字key1」的名次陣列(類似於給每個位置開始的子串分配乙個名次/權值 一開始乙個字元r[i]=a[i])
k為「第二關鍵字key2」的排序結果
k[i]表示的是按key2排序後第i名整個子串(key1+key2)開始的位置,不是key2開始的位置
可以發現key1開始位置+j=key2開始位置
先給單個字元計數排序
然後從j=1開始(每次迴圈是把兩個j合成j<<1)
p最後是當前不同的子串(不一定是字尾)的個數,p==n就沒必要繼續排序了(已經可以區分每個位置開始的字串的大小關係了)
1.給key2排序:先處理沒有key2的(n-j+1...n),再通過上一次排序後的sa得到k(上次sa就是長度j的結果,這次的乙個關鍵字長度也是j,只要sa[i]-j變成key1開始的位置就行了)
2.這時r[k[i]]就是key2排第i名的key1的權值,k[i]就是i的開始位置,計數排序,結果用sa儲存
3.更新r為長度j<<1時的名次,把r複製給k,這個名次會有相同的,應該算乙個,用離散化去重的寫法....如何判斷相同:先判斷是不是都有key2,有乙個沒有key2的話兩個一定不相同(長度就不可能相同了啊),再分別判斷兩個關鍵字是否相同(這時的k是長度j時的名次,判斷就行了)
「這裡和**裡不太一樣,他的做法是加了乙個0....」
【求lcp】
height陣列:定義 height[i]=suffix(sa[i-1])和 suffix(sa[i])的最長公共字首
排名i和排名i-1字尾的lcp
對於第i名和第j名,他們的lcp就是rmq
定義h[i]=height[rank[i]]
第i個字尾和在它的前一名的字尾的lcp。
性質: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)。證明也就是說第i個和他的前一名的lcp至少是i-1和它的前一名的lcp-1,直觀上理解,i-1往後一位(長度-1)就是i啊
實現上,並沒有必要弄乙個h,只需要按照h的順序(也就是原來1..n的順序)算就行了
注意:m的大小最後會為n,所以c陣列至少為n
voidgetheight()
}inline
bool cmp(int *r,int a,int b,int
j)
void
getsa()
}int lcp(int x,int
y)
字尾陣列學習筆記
要用好字尾陣列要先理解裡面幾個陣列的概念 sa i 表示字典序第i大的字尾下標 字典序排名依次是1 len stri ng ra nk i 表示下標為i的字尾字典序排名 he ight i 表示sa i 和sa i 1 最長公共字首的長度.乙個性質 lc p su ffix i suff ix j ...
字尾陣列 學習筆記
字尾陣列是處理字串的強有力的工具 在字串處理當中,字尾樹和字尾陣列都是非常有力的工具。其實字尾陣列是字尾樹的乙個非常精巧的替代品,它比字尾樹容易程式設計實現,能夠實現字尾樹的很多功能而時間複雜度也不太遜色,並且,它比字尾樹所占用的空間小很多。可以說,在資訊學競賽中字尾陣列比字尾樹要更為實用。我們定義...
字尾陣列 學習筆記
剛剛學完回文自動機 來學字尾陣列 一開始思路看得懂 但是 看不懂呀 一堆神仙 洛谷p3809 勿謂我,何強過者,炸哉!我們需要一種新的演算法 字尾陣列 首先,輸入字串 scanf s ch 1 n strlen ch 1 然後,按照題意 suffix sort ch for int i 1 i n ...