首先一定要確定sa
是個什麼東西 sa
[i] 表示的是排名為
i 的字尾是哪乙個
至於字尾
i的排名是多少,那個是ra
nk[i
] 當然啦
最最最難懂的就是基數排序
要是不用基數排序,每次對於乙個二元組直接so
rt一下
這樣的複雜度是o(
nlog
2)
對於二元組的基數排序應該是這樣做的:
首先把所有元素按照最後一維丟到依次對應的桶裡面
然後順次取出
再按照第一維依次丟入
再順次取出
這樣就可以排序啦
先把**丟出來
bool cmp(int i,int j,int k)
void getsa()
}
首先,第一次做k=
0 時
相當於每個字尾的第二維都是一樣的
所以,直接按照第一維(也就是自己的值)
進行一次基數排序
接下來
每次基數排序都要利用到上一次的值
還記得吧,基數排序是先按照第二維從小往大拍
那麼,我們就先把第二維的順序搞出來
首先最小的一定就是沒有第二維的東西
所以我們先把這些數直接丟進陣列裡面
接下來就是有第二維的東西啦 第i
位的第二維是啥?ra
nk[i
+k]所以,從小到達列舉sa
,這樣保證第二維從小往大
那麼,只要sa
[i]>k
就證明它是乙個東西的第二維
所以,把sa
[i]−
k 丟到陣列裡面去就好啦
這樣的話,按照第二維就拍好啦
再來依次按照第一維丟到桶裡面去
做一遍基數排序就好啦
這樣就能夠求出sa
啦看起來很簡單誒。。
只是陣列不要搞混了
一定搞清楚每個陣列是幹啥的
比如我的** sa
是字尾陣列,sa
[i] 表示排名為
i 的串是哪乙個 ra
nk相當於排名,ra
nk[i
] 表示第
i 個串的排名 x,
y兩個陣列是記錄順序的
分別記錄第一維和第二維的排序的順序
t 是桶
這樣我們就很愉快的求出了sa
還有乙個陣列he
ight
height[
i]表示串sa
[i] 與sa
[i−1
] 的最長公共字首的長度
比如說,現在要求字尾
i 與
j的最長公共字首
那就只需要求mi
n(he
ight
[i])
,i∈[
rank
[i]+
1,ra
nk[j
]]因為已經按照字典序排好序啦he
ight
顯然可以暴力求
但是太不優美
我們有hei
ght[
rank
[i]]
>=he
ight
[ran
k[i−
1]]−
1 證明(來自hi
hoco
der )
設su那麼,我們按照raffix
(k) 是排在su
ffix
(i−1
) 前一名的字尾,
則它們的最長公共字首是he
ight
[ran
k[i−
1]] 那麼s
uffi
x(k+
1)將排在su
ffix
(i) 的前面(這裡要求he
ight
[ran
k[i−
1]]>
1 ,如果he
ight
[ran
k[i−
1]]≤
1 ,原式顯然成立) 並且s
uffi
x(k+
1)和su
ffix
(i) 的最長公共字首是he
ight
[ran
k[i−
1]]−
1 , 所以s
uffi
x(i)
和在它前一名的字尾的最長公共字首至少是he
ight
[ran
k[i−
1]]−
1
nk的順序來求he
ight
就行啦
for(int i=1;i<=n;++i)rank[sa[i]]=i;
for(int i=1,j=0;i<=n;++i)
填坑啦
最長可重疊重複k次子串
解決方法:
二分答案 每次c
heck
檢查是否有超過
k 個連續he
ight
大於二分值
最長不可重疊重複子串
解決方法:
還是二分答案
在一段連續超過二分值的he
ight
中 記錄s
a 的最大和最小值
檢查是否有重合即可
最長公共子串1
最長公共子串2
解決方法:
把所有串都接在一起
中間找乙個字典序為in
f 的字元鏈結在一起
二分乙個答案
檢查一段連續的滿足條件的he
ight
中 是否所有串都出現在一起
字尾陣列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演算法複雜一點,但...
SA 字尾陣列
首先一定要確定 sa 是個什麼東西 sa i 表示的是排名為 i 的字尾是哪乙個 至於字尾 i 的排名是多少,那個是 rank i 當然啦最最最難懂的就是基數排序 要是不用基數排序,每次對於乙個二元組直接 sort 一下 這樣的複雜度是 o nlog 2 對於二元組的基數排序應該是這樣做的 首先把所...