可持久化資料結構1

蒟蒻之首發表於2024-08-20

非持久化資料結構一般需要維護資料集最新狀態,而可持久化要求查詢歷史狀態。

可持久化Trie樹

樸素:每次修改重新存一遍 \(-> MLE\)

正解:只存被修改部分,其餘不變,即第 \(i\) 次修改後,樹變為第 \(i\) 次修改產生新的部分加上前 \(i-1\) 次修改產生部分。

增長同規模。

用普通線段樹維護,\(m\) 次操作,時間複雜度 \(O(4n+mlog_n)\)

可持久化線段樹

例:單點修改,查詢區間最大值

\(a[x]\) 加上 \(d\),從表示 \(x\) 位置的葉子節點修改到根

修改時,對所有會被修改的點重開一樹,樹上未修改的點與新圖父親連邊,被修改的點複製連邊

更新 \(p\) 節點時,若 \(p\) 不為葉子,則其左右兒子之一也會被修改

假設 \(ls\) 被更新,\(ls\) 遞迴時,令 \(p'\) 左兒子為 \(ls'\),右兒子為 \(rs\)

空間複雜度 \(O(4n+mlog_n)\)

由於樹中每個點只有一個父親,而可持久化線段樹有多個根,所以只能用動態開點的方法編號

主席樹(可持久化權值線段樹)

區間第 \(k\) 小:
\(root[r]->\) 在值域區間 \([x,y]\)\(cnt_1\)

\(root[l-1]->\) 在值域區間 \([x,y]\)\(cnt_2\)

插入次序在 \([l,r]\) 之間,且值域在 \([x,y]\) 之間數字個數:\(cnt_1-cnt_2\)

\(i\) 棵線段樹儲存從第一次插入到第 \(i\) 次插入資訊

序列問題 \(->\) 樹上問題

\(tree[i]\) 表示從根節點到 \(i\) 的路徑上資訊(值域上區間和)

\(tree[u]+tree[v]-tree[lca]-tree[fa(lca)]\)

區間第 \(k\) 小(帶單點修改):

線段樹看成樹狀陣列上一元素

設樹狀陣列中下標 \(i\) 所記錄資訊集合為 \(S_i\),那麼我們定義線段樹 \(T_i\) 是維護 \(S_i\) 內資訊的所有點的集合

相關文章