這題和普通的第k大類似。
普通的第k大,是從後往前建立主席樹,前乙個在後乙個的基礎上修改。
而樹上第k大,依舊是每個結點一棵主席樹,是在父節點的基礎上修改。
那麼可以發現這棵主席樹是包括所有祖先結點的(就是深度在當前結點之上的)
查詢的時候,是兩個結點的值的和,還要減掉lca以上的部分。同時要注意處理lca這個 結點的值。
主要不同便是建樹是根據父結點,以前查詢的時候注意兩個主席樹的公共部分。
#include#define m 10000005
#define n 110005
using namespace std;
int n, q, a[n];
vectoredge[n];
int t[n], m;
void init_hash()
int hash(int x)
int t[m], lson[m], rson[m], c[m], tot = 0;
int bulid(int l, int r)
return root;
}int update(int root, int pos, int val)
else
c[newroot] = c[root] + val;
}return tmp;
}int query(int left_root, int right_root, int lca, int k)
else
}return l;
}/* 主席樹部分 */
/* lca部分 */
int depth = 0, b[n * 2], cnt = 0;
int p[n], f[n];
void dfs(int u, int pre)
}int dp[n * 2][20];
void init_rmq(int n)
int rmq(int l, int r)
int lca(int a, int b)
/* lca部分 */
int main()
init_hash();
t[0] = bulid(1, m);
dfs(1, 0);
init_rmq(cnt);
while (q--)
return 0;
}
樹上主席樹 查詢樹鏈上第K大
給定一棵n個節點的樹,每個點有乙個權值,對於m個詢問 u,v,k 你需要回答u xor lastans和v這兩個節點間第k小的點權。其中lastans是上乙個詢問的答案,初始為0,即第乙個詢問的u是明文。第一行兩個整數n,m。第二行有n個整數,其中第i個整數表示點i的權值。後面n 1行每行兩個整數 ...
(LCA 樹上主席樹)FZU 2237 中位數
題意 多次查詢乙個樹鏈上的中位數 其實就是求k大 分析 感覺莫隊可做,只是不會樹上莫隊。而且這裡是邊權,處理起來貌似有點小麻煩。後來發現其實貌似是乙個很老的題,kuangbin模板書上有類似的題。樹鏈上的第k大數,這是一道可以用主席樹解的題,複雜度才nlogn。這裡也是這樣先求從根到每個點的線段樹,...
區間第k大(主席樹)
學了一下主席樹模板題,當初看了網上的主席樹講解都沒有看懂,後面看了嗶哩嗶哩的uestc的主席樹,終於看懂了思想。每次更新的複雜度都為logn。每次更新的話就是對要更新的點路徑上的點重新更加乙個,然後進行對沒有影響的那些進行連邊。然後用乙個root記錄每乙個線段樹的根節點下標。include incl...