K-D Tree 學習筆記
阿新 • • 發佈:2020-12-17
又是一個不需要證明的東西,複雜度基本玄學。
具體來說 K-D Tree 是解決高維問題的一個數據結構(其實一般是二維)。
K-D Tree 本質上是一棵二叉搜尋樹,其的基本思想就是遍歷整個狀態空間加剪枝。
設問題維度是K,其單次查詢的複雜度大概是 \(O(n^{\frac{K-1}{K}})\)。
K-D Tree 的建樹方法
我們一般採用每次隨機找一個維度,以這個維度排序,且以這個維度的中位數為根的方法。
這種方法基本上不會被卡。
一般來說我們維度的選擇就是從 1-K 反覆迴圈進行的。
K-D Tree 的查詢方法
這個就具體問題具體分析了,說幾個經典問題吧。
最遠點
找距離一個座標最遠的點。
這個比較簡單,維護每顆子樹裡每一維最大和最小的值,然後一一配對取最大值就可以了。
最近點
這個就比較妙了。
我們依舊維護每顆子樹裡每一維最大和最小的值;
然後對於每一維我們找到理想狀態下距離最近的點,加入答案中。
其實本質上是 A*。
算了,給個程式碼實現吧。
int getmin(int rt, int x, int y, int res = 0) { for(register int i = 0; i < 2; ++i) { if(i == 1) x = y; res += max(0, tr[rt].mi[i] - x); res += max(0, x - tr[rt].mx[i]); } return res; }
K遠點
一般來說 K 不會很大。
這個我們可以開個小根堆,初始時堆裡有 K 個元素。
查詢時每次替換最小的那個就可以了。
動態插入
主要利用的是替罪羊的思想。
插入的話我們直接向平衡樹那樣插入就可以了。
維護平衡因子,適時推翻重建以維護平衡。
(暫時沒有寫過)