定義:
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...