trie上構建後綴數組和波蘭表

普通後綴數組的倍增構建

​ 對於單個字符串上的後綴數組的建造,一般都是倍增一個長度l ,然後對於當前的排序組,每隔l 就把兩個元素並在一起,拿這兩個東西分別作爲兩個關鍵字再排序,直到倍增長度大於字符串長。其實這個倍增算法如果在trie上也是同樣適用。

trie上後綴數組的倍增構建

​ 對於一個trie,我們同樣可以通過倍增來求,只要把在序列上倍增k 級變成樹上的倍增k 級祖先應該就可以了。如果我們把倍增的過程時的rk 數組記錄下來,我們就得到一個神奇的東西——用vfk的話來說就是波蘭表。

​ 似乎在trie上SA建H數組有點不好搞,怎麼辦呢?沒事,我們有波蘭表!對於相鄰的兩個後綴,我們可以用記錄下來的krk 的信息來搞,然後類似倍增那樣判斷其k 級的排名是否相同,然後就可以求出LCP了。

​ 代碼大概是這樣:

void build() {
    rep (i , 1 , n) rk[i][0] = str[i];
    rep (i , 1 , n) pa[i][0] = fa[i];
    rep (j , 1 , lg) {
        rep (i , 1 , n)
            pos[i] = mp(mp(rk[i][j - 1] , rk[pa[i][j - 1]][j - 1]) , i) ,
            pa[i][j] = pa[pa[i][j - 1]][j - 1];
        sort(pos + 1 , pos + n + 1);
        rk[pos[1].sec][j] = 1;
        int p = 1;
        rep (i , 2 , n)
            rk[pos[i].sec][j] = (pos[i - 1].fir == pos[i].fir) ? p : ++ p;
    }
}

int LCP(int u , int v) {
    if (u == v)
        dep[u];
    int l = 0;
    per (i , lg , 0) if (rk[u][i] == rk[v][i]) {
        l += 1 << i;
        u = pa[u][i] , v = pa[v][i];
    }
    return l;
}
發佈了135 篇原創文章 · 獲贊 6 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章