一道模板題
字尾陣列(sa)是乙個比較強大的處理字串的演算法,是有關字串的比較基礎是嗎?演算法,所以必須掌握
實現主要有倍增和dc
3 ,而我太弱了只學了倍增
s :就是這個字串,長度為le
nran
k[i]
:表示i到
len 這個字尾在所有字尾中的排名 sa
[i] :表示排名為
i 的字尾的首字元下標 he
ight
[i]:表示相鄰兩個排名的字尾的最長公共字首的長度 h[
i]:表示i到
len 這個字尾與它前一名字尾的最長公共字首的長度,就是he
ight
[ran
k[i]
]首先基數排序:就是低位到高位一位一位桶排,詳見baidu
怎麼排序?
如果一位一位來,那不就成了暴力了
所以我們要倍增排序
具體來說,對於乙個長度為2k
的字串,我們可以把它看成是兩個長度為2k
−1的字串組成的,那麼就相當於它有兩個關鍵字,我們就從長度為
1 開始,每次對這兩個關鍵字排序不就行了
一張古老的圖
看**
# include
# define il inline
# define rg register
# define fill(a, b) memset(a, b, sizeof(a))
using
namespace
std;
typedef
long
long ll;
const
int _(1e6 + 5);
int len, sa[_], t[_], a[_], rk[_], y[_];
char s[_];
//t是桶;a和s一樣;rk就是rank;y是輔助rk的陣列,和sa性質相似;sa就是sa
il bool cmp(rg int i, rg int j, rg int k) //確定兩個子串是否相同
il void sort()
}int main(rg int argc, rg char* argv)
有點難理解,多看幾個部落格就可以了有個s
a和ra
nk並沒有什麼卵用,這個時候就有he
ight
這個美妙的東西
怎麼求?
暴力求o(n
2)顯然不行
那麼這個時候要利用
h 的美妙性質:h[
i]≥h
[i−1
]−1證明:設字尾su
f[k]
和suf
[i−1
] 為兩個相鄰排名的字尾,它們的最長公共字首就是h[
i−1]
同時去掉第乙個字元,那麼就是su
f[k+
1]和s
uf[i
] ,那它們兩個的最長公共字首顯然就是h[
i−1]
−1所以su
f[i]
和排在它前面的字尾的最長公共字首至少是h[
i−1]
−1
那麼h就可以很快求出來了,那麼he
ight
也就能很快求出來了
for(rg int i = 1; i <= len; ++i)
for(rg int i = 1; i <= len; ++i) height[i] = h[sa[i]];
剛剛學**比較醜,而且可能有問題
題去這裡找
題去這裡找
題:給定乙個字串,詢問某兩個字尾的最長公共字首。
就是區間he
ight
的最小值,rm
q 問題
重複子串:字串a在字串b中至少出現兩次,則稱a是b的重複子串。
題:給定乙個字串,求最長重複子串,重複的兩個子串可以重疊。
分析:
只需要求 height 陣列裡的最大值即可
題:給定乙個字串,求最長重複子串,重複的兩個子串不能重疊。
分析:
考慮二分答案,每次二分乙個答案
k ,把he
ight
=k 分組
最長公共字首不小於 k 的兩個字尾一定在同一組。對於每組字尾,只須判斷每個字尾的 sa 值的最大值和最小值之差是否不小於k即可
另外:利用 height 值對字尾進行分組的方法很常用
題:給定乙個字串,求至少出現 k 次的最長重複子串,這 k 個子串可以重疊
分析:
也是二分答案+分組,判斷有沒有乙個組的字尾個數不小於 k
題:給定乙個字串,求不相同的子串的個數。
分析:
每個子串一定是某個字尾的字首,也就是求所有字尾不同字首的個數
每來乙個字尾su
f(i)
就會有,le
n−sa
[i]+
1 的新的字首,又由於有he
ight
個重複的,那麼就是le
n−sa
[i]+
1−he
ight
的貢獻還有很多用法見下面的文獻
羅穗騫 –演算法合集之《字尾陣列——處理字串的有力工具》
字尾陣列小結
搞了這麼多字尾陣列,寫個總結 其實羅穗賽的 裡已經都總結得很清楚了。我這裡對一些 的具體實現細節和一些要注意的地方做一些說明。字尾陣列很重要的三個陣列就是 rank,sa和height了 其中rank i 表示i這個字尾的排名,sa i 表示排在第i位的字尾的首字母位置,height i 表示排名第...
字尾陣列小結
我為什麼要叫小結呢這明明就是個題解包啊 直接偷迪哥的就好辣 差異 大概是個板子,求出 height 陣列後直接單調棧即可 相似子串 首先 子串是字尾的字首 其次 每個字尾貢獻的本質不同子串的數量是 n i 1 he i 因為子串過多所以我們考慮運用上文性質來二分查排名 至於相似度 rmq 即可?sa...
字尾陣列學習小結
這兩天學習了字尾陣列,感想是,果然字尾陣列比網路流可愛的多,就像字串比圖論可愛的多。有模板真好qvq。總結了一下字尾陣列的幾個要點 一.理解rank sa height三個陣列。分別代表所構成的字尾陣列str i 在程式裡並不表現出來 排名後的名次 排名後第i位是str中的哪乙個 str sa i ...