字尾陣列複習小記

2021-07-31 03:08:34 字數 1084 閱讀 8579

定義:

suf[i]表示以i為開頭的字尾

rank[i]表示suf[i]的排名,sa[i]表示排名為i的字尾

height[i]表示sa[i]和sa[i-1]的lcp

h[i]表示suf[i]和suf[sa[rank[i]-1]]的lcp

sa[rank[i]]=i,所以只要能求出rank,就可以求sa

倍增 求rank相當於把n個字尾排序,直接暴力排,顯然是o(n^2*log(n))

我們可以考慮假如已經處理了每個位置開始的長度為k的字串的排名,對於下一次排序,對於乙個位置i我們可以以i的排名為第一關鍵字,以i+k的排名為第二關鍵字(i+k>n記做0),那麼我們就可以處理出每個位置開始的長度為2k的字串的排名。

也就是log(n)次即可,如果每次用快排那就是o(nlog^2n)

每次的排名肯定是<=n的,那我們用基數排序就可以o(n)排序。

對於兩個關鍵字的基數排序,我們可以先處理出每個數的第二關鍵字的排名,然後對第一關鍵字排序時按第二關鍵字的排名插入即可。

如何處理height呢?

我們可以直接求h,因為height[rank[i]]=h[i]

有乙個很好的性質h[i]>=h[i+1]-1,利用這個就可以做到o(n)處理height

簡單應用

兩個字尾suf[i]和suf[j]的lcp=的最小值

void

getsa()

for(;num

fo(i,1,n) rank[i]=c[i];

k<<=1;

}k=0;

fo(i,1,n)

fo(i,1,n) w[i][0]=height[i];

two[0]=1;

fo(i,1,19)two[i]=two[i-1]<<1;

j=0;

fo(i,1,n)

fo(j,1,18)

fo(i,1,n-two[j]+1) w[i][j]=min(w[i][j-1],w[i+two[j-1]][j-1]);

}int

lcp(int

x,int

y)

字尾陣列複習小記

字尾陣列,顧名思義就是處理字尾的陣列。例如daabbc的字尾 daabbc,aabbc,abbc,bbc,bc,c六個字尾。定義sa i 為排名第i個的字尾的第乙個字元在原字串中的序號。如上面的sa 1 2,因為字尾從序號2開始的aabbc排第乙個。定義rank i 為序號從i開始的字尾排第幾個。如...

字尾陣列小記

sa i 表示第 i 小的字尾對應原串的位置 rk i 表示第 i 個字尾的排名 x i 表示第 i 個字尾的第一關鍵字排名,即當前的 rk i y i 表示第 i 小的第二關鍵字對應的第幾個字尾 c i 是乙個計數陣列,用於基數排序用 考慮倍增,每次從 2 k 轉移到 2 可以發現每個 2 串可以...

字尾陣列複習

一下排名均是在字典序下的排名 sa i 排名為 i 的字尾的編號 rank i 第 i 個字尾串的排名 有 rank sa i i 和 sa rank i i height i 排名為 i 的字尾和排名為 i 1 的字尾的最長公共字首 模板 include include include using...