You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer weight.

We will ask you to perform the following operation:

  • u v k : ask for the kth minimum weight on the path from node u to node v

Input

In the first line there are two integers N and M. (N, M <= 100000)

In the second line there are N integers. The ith integer denotes the weight of the ith node.

In the next N-1 lines, each line contains two integers u v, which describes an edge (uv).

In the next M lines, each line contains three integers u v k, which means an operation asking for the kth minimum weight on the path from node u to node v.

Output

For each operation, print its result.

Example

  1. Input:
  2. 8 5
  3. 105 2 9 3 8 5 7 7
  4. 1 2
  5. 1 3
  6. 1 4
  7. 3 5
  8. 3 6
  9. 3 7
  10. 4 8
    2 5 1
    2 5 2
    2 5 3
    2 5 4
    7 8 2 
  1. Output:
  2. 2
    8
    9
    105
    7 
    给出一棵树,每个点都自己的权重,然后给出树上的边,要求从节点 u 到节点 v 路径上的第 k 小的权重的大小。
    因为权重可能很大,所以需要离散化。
    主席树求区间第 k 小维护的是权值线段树的前缀和,然后通过区间相减得到查询区间的权值线段树
    所以树形结构的第 k 小维护的也是权值线段树的前缀和,这里的前缀和表示从第 i 个结点到根的前缀和,比如样例的树是

那么我们用主席树把这八个结点维护成这个样子

那么要得到其中两个点(u,v)之间的树形结构,就可以看成 TREE(u) + TREE(v) - TREE(lca(u,v))- TREE(fa(lca(u,v))),把查询看成四棵树之间的相加相减,然后在求一下lca(u,v)就可以了,这里我比较懒直接用在线的写了

  1. /*
  2. .
  3. ';;;;;.
  4. '!;;;;;;!;`
  5. '!;|&#@|;;;;!:
  6. `;;!&####@|;;;;!:
  7. .;;;!&@$$%|!;;;;;;!'.`:::::'.
  8. '!;;;;;;;;!$@###&|;;|%!;!$|;;;;|&&;.
  9. :!;;;;!$@&%|;;;;;;;;;|!::!!:::;!$%;!$%` '!%&#########@$!:.
  10. ;!;;!!;;;;;|$$&@##$;;;::'''''::;;;;|&|%@$|;;;;;;;;;;;;;;;;!$;
  11. ;|;;;;;;;;;;;;;;;;;;!%@#####&!:::;!;;;;;;;;;;!&####@%!;;;;$%`
  12. `!!;;;;;;;;;;!|%%|!!;::;;|@##%|$|;;;;;;;;;;;;!|%$#####%;;;%&;
  13. :@###&!:;;!!||%%%%%|!;;;;;||;;;;||!$&&@@%;;;;;;;|$$##$;;;%@|
  14. ;|::;;;;;;;;;;;;|&&$|;;!$@&$!;;;;!;;;;;;;;;;;;;;;;!%|;;;%@%.
  15. `!!;;;;;;;!!!!;;;;;$@@@&&&&&@$!;!%|;;;;!||!;;;;;!|%%%!;;%@|.
  16. %&&$!;;;;;!;;;;;;;;;;;|$&&&&&&&&&@@%!%%;!||!;;;;;;;;;;;;;$##!
  17. !%;;;;;;!%!:;;;;;;;;;;!$&&&&&&&&&&@##&%|||;;;!!||!;;;;;;;$&:
  18. ':|@###%;:;;;;;;;;;;;;!%$&&&&&&@@$!;;;;;;;!!!;;;;;%&!;;|&%.
  19. !@|;;;;;;;;;;;;;;;;;;|%|$&&$%&&|;;;;;;;;;;;;!;;;;;!&@@&'
  20. .:%#&!;;;;;;;;;;;;;;!%|$$%%&@%;;;;;;;;;;;;;;;;;;;!&@:
  21. .%$;;;;;;;;;;;;;;;;;;|$$$$@&|;;;;;;;;;;;;;;;;;;;;%@%.
  22. !&!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|@#;
  23. `%$!;;;;;;;;;;;$@|;;;;;;;;;;;;;;;;;;;;;;;;!%$@#@|.
  24. .|@%!;;;;;;;;;!$&%||;;;;;;;;;;;;;;;;;!%$$$$$@#|.
  25. ;&$!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%#####|.
  26. |##$|!;;;;;;::'':;;;;;;;;;;;;;!%$$$@#@;
  27. ;@&|;;;;;;;::'''''':;;;;;;;|$&@###@|`
  28. .%##@|;;;;:::''''''''''::;!%&##$'
  29. `$##@$$@@&|!!;;;:'''''::::;;;;;|&#%.
  30. ;&@##&$%!;;;;;;::''''''''::;!|%$@#@&@@:
  31. .%@&$$|;;;;;;;;;;:'''':''''::;;;%@#@@#%.
  32. :@##@###@$$$$$|;;:'''':;;!!;;;;;;!$#@@#$;`
  33. `%@$$|;;;;;;;;:'''''''::;;;;|%$$|!!&###&'
  34. |##&%!;;;;;::''''''''''''::;;;;;;;!$@&:`!'
  35. :;!@$|;;;;;;;::''''''''''':;;;;;;;;!%&@$: !@#$'
  36. |##@@&%;;;;;::''''''''':;;;;;;;!%&@#@$%: '%%!%&;
  37. |&%!;;;;;;;%$!:''''''':|%!;;;;;;;;|&@%||` '%$|!%&;
  38. |@%!;;!!;;;||;:'''''':;%$!;;;;!%%%&#&%$&: .|%;:!&%`
  39. !@&%;;;;;;;||;;;:''::;;%$!;;;;;;;|&@%;!$; `%&%!!$&:
  40. '$$|;!!!!;;||;;;;;;;;;;%%;;;;;;;|@@|!$##; !$!;:!$&:
  41. |#&|;;;;;;!||;;;;;;;;!%|;;;;!$##$;;;;|%' `%$|%%;|&$'
  42. |&%!;;;;;;|%;;;;;;;;$$;;;;;;|&&|!|%&&; .:%&$!;;;:!$@!
  43. `%#&%!!;;;;||;;;;;!$&|;;;!%%%@&!;;;!!;;;|%!;;%@$!%@!
  44. !&!;;;;;;;;;||;;%&!;;;;;;;;;%@&!;;!&$;;;|&%;;;%@%`
  45. '%|;;;;;;;;!!|$|%&%;;;;;;;;;;|&#&|!!||!!|%$@@|'
  46. .!%%&%'`|$; :|$#%|@#&;%#%.
  47. */
  48. #include <map>
  49. #include <set>
  50. #include <list>
  51. #include <ctime>
  52. #include <cmath>
  53. #include <stack>
  54. #include <queue>
  55. #include <string>
  56. #include <vector>
  57. #include <cstdio>
  58. #include <bitset>
  59. #include <cstdlib>
  60. #include <cstring>
  61. #include <iostream>
  62. #include <algorithm>
  63. #define lowbit(x) x & (-x)
  64. #define mes(a, b) memset(a, b, sizeof a)
  65. #define fi first
  66. #define se second
  67. #define pii pair<int, int>
  68. #define INOPEN freopen("in.txt", "r", stdin)
  69. #define OUTOPEN freopen("out.txt", "w", stdout)
  70.  
  71. typedef unsigned long long int ull;
  72. typedef long long int ll;
  73. const int maxn = 1e5 + ;
  74. const int maxm = 1e5 + ;
  75. const int mod = 1e9 + ;
  76. const ll INF = 1e18 + ;
  77. const int inf = 0x3f3f3f3f;
  78. const double pi = acos(-1.0);
  79. const double eps = 1e-;
  80. using namespace std;
  81.  
  82. int n, m;
  83. int cas, tol, T;
  84.  
  85. struct Node {
  86. int l, r;
  87. int sum;
  88. } node[maxn * ];
  89. int a[maxn];
  90. int rt[maxn];
  91. bool vis[maxn];
  92. int deep[maxn];
  93. int fa[maxn][];
  94. vector<int> vec[maxn];
  95. vector<int> vv;
  96.  
  97. void init() {
  98. tol = ;
  99. mes(a, );
  100. mes(rt, );
  101. mes(fa, );
  102. mes(vis, );
  103. mes(node, );
  104. mes(deep, );
  105. vv.clear();
  106. for(int i=; i<=n; i++)
  107. vec[i].clear();
  108. }
  109.  
  110. int getid(int x) {
  111. return lower_bound(vv.begin(), vv.end(), x) - vv.begin() + ;
  112. }
  113.  
  114. void lca_dfs(int u, int f, int d) {
  115. deep[u] = d;
  116. int len = vec[u].size();
  117. for(int i=; i<len; i++) {
  118. int v = vec[u][i];
  119. if(v == f) continue;
  120. if(fa[v][])continue;
  121. fa[v][] = u;
  122. lca_dfs(v, u, d+);
  123. }
  124. }
  125.  
  126. void lca_update() {
  127. for(int j=; (<<j)<=n; j++) {
  128. for(int i=; i<=n; i++) {
  129. fa[i][j] = fa[fa[i][j-]][j-];
  130. }
  131. }
  132. }
  133.  
  134. int lca_query(int u, int v) {
  135. if(deep[u] < deep[v]) swap(u, v);
  136. int f = deep[u] - deep[v];
  137. for(int i=; (<<i)<=f; i++) {
  138. if(f & (<<i)) {
  139. u = fa[u][i];
  140. }
  141. }
  142. if(u != v) {
  143. for(int i=(int)log2(n); i>=; i--) {
  144. if(fa[u][i] != fa[v][i]) {
  145. u = fa[u][i];
  146. v = fa[v][i];
  147. }
  148. }
  149. u = fa[u][];
  150. }
  151. return u;
  152. }
  153.  
  154. void hjt_update(int l, int r, int &x, int y, int pos) {
  155. tol++;
  156. node[tol] = node[y];
  157. node[tol].sum++;
  158. x = tol;
  159. if(l == r) return ;
  160. int mid = (l + r) >> ;
  161. if(pos <= mid)
  162. hjt_update(l, mid, node[x].l, node[y].l, pos);
  163. else
  164. hjt_update(mid+, r, node[x].r, node[y].r, pos);
  165. }
  166.  
  167. void hjt_build(int u, int f) {
  168. // printf("%d %d\n", u, f);
  169. hjt_update(, n, rt[u], rt[f], getid(a[u]));
  170. vis[u] = true;
  171. int len = vec[u].size();
  172. for(int i=; i<len; i++) {
  173. int v = vec[u][i];
  174. if(vis[v]) continue;
  175. if(v == f) continue;
  176. hjt_build(v, u);
  177. }
  178. }
  179.  
  180. int hjt_query(int l, int r, int x, int y, int lca, int flca, int k) {
  181. if(l == r)
  182. return l;
  183. int mid = (l + r) >> ;
  184. int sum = node[node[x].l].sum + node[node[y].l].sum - node[node[lca].l].sum - node[node[flca].l].sum;
  185. if(k <= sum)
  186. return hjt_query(l, mid, node[x].l, node[y].l, node[lca].l, node[flca].l, k);
  187. else
  188. return hjt_query(mid+, r, node[x].r, node[y].r, node[lca].r, node[flca].r, k-sum);
  189. }
  190.  
  191. int main() {
  192. scanf("%d%d", &n, &m);
  193. init();
  194. for(int i=; i<=n; i++) {
  195. scanf("%d", &a[i]);
  196. vv.push_back(a[i]);
  197. }
  198. sort(vv.begin(), vv.end());
  199. vv.erase(unique(vv.begin(), vv.end()), vv.end());
  200. for(int i=; i<n; i++) {
  201. int u, v;
  202. scanf("%d%d", &u, &v);
  203. vec[u].push_back(v);
  204. vec[v].push_back(u);
  205. }
  206. fa[][] = ;
  207. lca_dfs(, , );
  208. lca_update();
  209. hjt_build(, );
  210. while(m--) {
  211. int u, v, k;
  212. scanf("%d%d%d", &u, &v, &k);
  213. int ans = hjt_query(, n, rt[u], rt[v], rt[lca_query(u, v)], rt[fa[lca_query(u, v)][]], k);
  214. printf("%d\n", vv[ans-]);
  215. }
  216. return ;
  217. }

Count on a tree SPOJ - COT (主席树,LCA)的更多相关文章

  1. Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)

    Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...

  2. SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解

    题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...

  3. 【BZOJ2588】Count on a tree 题解(主席树+LCA)

    前言:其实就是主席树板子啦……只不过变成了树上的查询 -------------------------- 题目链接 题目大意:求树上$u$到$v$路径第$k$大数. 查询静态区间第$k$大肯定是用主 ...

  4. ☆ [洛谷P2633] Count on a tree 「树上主席树」

    题目类型:主席树+\(LCA\) 传送门:>Here< 题意:给出一棵树.每个节点有点权.问某一条路径上排名第\(K\)小的点权是多少 解题思路 类似区间第\(K\)小,但放在了树上. 考 ...

  5. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  6. BZOJ2588 Count on a tree 【树上主席树】

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7577  Solved: 185 ...

  7. 【洛谷2633】Count on a tree(树上主席树)

    点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...

  8. 🔺Count on a tree SPOJ - COT (无能为力。。。)

    https://cn.vjudge.net/problem/SPOJ-COT 插上 大佬的代码 和 我的...以后再看吧... Count on a tree 大佬:http://www.cnblog ...

  9. BZOJ - 2588 Spoj 10628. Count on a tree (可持久化线段树+LCA/树链剖分)

    题目链接 第一种方法,dfs序上建可持久化线段树,然后询问的时候把两点之间的所有树链扒出来做差. #include<bits/stdc++.h> using namespace std; ...

随机推荐

  1. 更新下载库update绝对详解

    下载更新apk,基本上每个app都需要的功能,来看看吧,肯定有你想要的,以前都是自己写,近期想借助第三方的一个库来做,功能齐全,感觉不错,记录使用过程,虽然官方也有使用教程,不过毕竟粗略,网上也能搜到 ...

  2. 模拟ES6中的Promise实现,让原理一目了然

    简介 Promise 对象用于延迟(deferred) 计算和异步(asynchronous )计算.一个Promise对象代表着一个还未完成,但预期将来会完成的操作.Promise 对象是一个返回值 ...

  3. 在java中写出完美的单例模式

    1. 前言 单例(Singleton)应该是开发者们最熟悉的设计模式了,并且好像也是最容易实现的——基本上每个开发者都能够随手写出——但是,真的是这样吗? 作为一个Java开发者,也许你觉得自己对单例 ...

  4. 用 Weave Scope 监控集群 - 每天5分钟玩转 Docker 容器技术(175)

    创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所有必要组件就位并各司其职,有足够的资源满足应用的需求.Kubernetes 是一个复杂系统,运维团 ...

  5. 【原】Java学习笔记018 - 面向对象

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 继承关系的子类可以 ...

  6. 树莓派3b+ Ubuntu 16.04 MATA系统 ssh远程登陆后修改主机名、用户密码和用户名

    写在前面: 刚刚开始写博客,记录下自己的学习过程,备忘. 最近在使用树莓派做智能小车的开发,使用的是树莓派3b+,安装的是Ubuntu 16.04 MATA 系统,安装系统后需要修改主机名,登陆密码以 ...

  7. Eclipse编程中免除alt+斜杠,设置自动提示

    用eclipse进行编程时,设置自动提示 .abcdefghijklmnopqrstuvwxyz@

  8. perf + Flame Graph火焰图分析程序性能

    1.perf命令简要介绍 性能调优时,我们通常需要分析查找到程序百分比高的热点代码片段,这便需要使用 perf record 记录单个函数级别的统计信息,并使用 perf report 来显示统计结果 ...

  9. nginx 499状态码

    Web服务器在用着nginx,在日志中偶尔会看到有499这个错误. rfc2616中,400-500间的错误码仅定义到了417,所以499应该是nginx自己定义的.后来想到读读nginx代码,疑问立 ...

  10. ###20175311MyCP(课下作业,必做)

    MyCP(课下作业,必做) 作业题目 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.b ...