BZOJ2588 Spoj 10628.Count on a tree 主席树+LCA

发布于 2017-08-05  6.3k 次阅读


[toggle hide="yes" title="题目" color=""]

Description
给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

Input
第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。

Output
M行,表示每个询问的答案。最后一个询问不输出换行符

Sample Input
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2

Sample Output
2
8
9
105
7

HINT:
N,M<=100000

[/toggle]

要查询树上点对间点权k大,不难想到为每个节点建立权值主席树,每个节点由其父节点的主席树扩展而来,所以只需在DFS时建树即可。查询时二分答案,差分一下,用root[u]+root[v]-root[lca(u,v)]-root[fa[lca(u,v)]]即可,思路比较简单。

 

 


Narcissus | HZOIer | zhuohaoyu1228@gmail.com | QQ 943382974