給定一棵樹,每個節點有權值。支持兩種操作:
u-v 上第 k 大權值。節點數 N ≤ 80000,操作數 Q ≤ 80000。
mid,統計路徑上 ≤ mid 的數量,利用線段樹套平衡樹單次查詢 O(log² N)。[L[u], R[u]]。root[u] 表示根到 u 路徑上的權值多集。查詢路徑 u-v 轉化為 root[u] + root[v] - 2*root[lca] + val[lca]。u 權值從 a 變 b,影響其子樹內所有節點的主席樹。利用 DFS 序區間 [L[u], R[u]],在樹狀數組上做區間增減:L[u] +1, R[u]+1 -1(針對值 b),L[u] -1, R[u]+1 +1(針對值 a)。// Splay 節點結構
struct Node { int ch[2], fa, val, sz, cnt; } t[NN];
// 線段樹節點掛 Splay 根
int root_seg[4*N], lc[4*N], rc[4*N];
// 操作:insert/del/splay/rotate/query_kth 等
// 主席樹節點
struct PSTNode { int lc, rc, sum; } pst[NN];
int root[N]; // 版本根
// BIT 維护修改
int bit[N];
void bit_add(int idx, int val_version) { for(; idx<=N; idx+=lowbit(idx)) bit[idx] = merge(bit[idx], val_version); }
// 查詢合併版本進行 K 大
| 維度 | 樹剖+線段樹套平衡樹 | DFS序+主席樹+BIT |
|---|---|---|
| 編碼難度 | 極高(三層數據結構嵌套) | 高(主席樹+BIT離線思想) |
| 查詢複雜度 | O(log³ N) | O(log² N) |
| 修改複雜度 | O(log² N) | O(log² N) |
| 常數因子 | 大(Splay 指針操作多) | 中(靜態數組實現主席樹) |
| 適用場景 | 在線查詢、需支持任意路徑聚合 | 權值域較小、適合離線/版本控制 |
本題兩種解法均屬經典高級數據結構應用,掌握其中任一即可解決樹上帶修改 K 大問題。