Code:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<string>
  5. #include<iostream>
  6.  
  7. using namespace std;
  8.  
  9. void SetIO(string a){
  10. string in = a + ".in";
  11. freopen(in.c_str(),"r",stdin);
  12. }
  13.  
  14. void debug(){
  15. cout << 233 << endl;
  16. }
  17.  
  18. const int maxn = 100000 + 5;
  19.  
  20. int n, m;
  21.  
  22. int val[maxn];
  23.  
  24. int Sorted[maxn];
  25.  
  26. inline void Disperse(){
  27. sort(Sorted + 1, Sorted + 1 + n);
  28. for(int i = 1;i <= n; ++i)
  29. val[i] = lower_bound(Sorted + 1, Sorted + 1 + n, val[i]) - Sorted;
  30. }
  31.  
  32. int head[maxn << 1], to[maxn << 1], nex[maxn << 1], edges;
  33.  
  34. inline void add_edge(int u, int v){
  35. nex[++edges] = head[u];
  36. head[u] = edges;
  37. to[edges] = v;
  38. }
  39.  
  40. inline void Read(){
  41. scanf("%d%d",&n, &m);
  42. for(int i = 1;i <= n; ++i){
  43. scanf("%d",&val[i]), Sorted[i] = val[i];
  44. }
  45.  
  46. for(int i = 1;i < n; ++i){
  47. int a, b;
  48. scanf("%d%d",&a,&b);
  49. add_edge(a,b);
  50. add_edge(b,a);
  51. }
  52. }
  53.  
  54. const int Tree_const = 50;
  55.  
  56. int root[maxn];
  57.  
  58. struct Chair_Tree{
  59. int cnt_node;
  60.  
  61. int sumv[maxn * Tree_const], lson[maxn * Tree_const], rson[maxn * Tree_const];
  62.  
  63. void build(int l, int r, int &o){
  64. if(l > r) return ;
  65. o = ++ cnt_node;
  66. if(l == r) return ;
  67. int mid = (l + r) >> 1;
  68. build(l, mid, lson[o]);
  69. build(mid + 1, r, rson[o]);
  70. }
  71.  
  72. int insert(int l, int r, int o, int pos){
  73. int oo = ++cnt_node;
  74. lson[oo] = lson[o];
  75. rson[oo] = rson[o];
  76. sumv[oo] = sumv[o] + 1;
  77.  
  78. if(l == r) return oo;
  79.  
  80. int mid = (l + r) >> 1;
  81. if(pos <= mid) lson[oo] = insert(l, mid, lson[o], pos);
  82. else rson[oo] = insert(mid + 1, r, rson[o], pos);
  83. return oo;
  84. }
  85.  
  86. int query(int l, int r, int u, int v, int lca, int lca_fa, int k){
  87. if(l == r) return l;
  88. int lsum = sumv[lson[u]] + sumv[lson[v]] - sumv[lson[lca]] - sumv[lson[lca_fa]];
  89. int mid = (l + r) >> 1;
  90. if(k <= lsum) return query(l, mid, lson[u], lson[v], lson[lca], lson[lca_fa], k);
  91. else return query(mid + 1, r, rson[u], rson[v], rson[lca], rson[lca_fa], k - lsum);
  92. }
  93.  
  94. }Tree;
  95.  
  96. const int logn = 20;
  97.  
  98. int f[23][maxn];
  99.  
  100. int dep[maxn];
  101.  
  102. void dfs(int u, int fa, int depth){
  103.  
  104. root[u] = Tree.insert(1, n, root[fa], val[u]);
  105. dep[u] = depth;
  106. f[0][u] = fa;
  107.  
  108. for(int v = head[u]; v ; v = nex[v]){
  109. if(to[v] == fa) continue;
  110. dfs(to[v], u, depth + 1);
  111. }
  112. }
  113.  
  114. inline void get_ancester(){
  115. for(int i = 1;i <= logn; ++i){
  116. for(int j = 1;j <= n; ++j)
  117. f[i][j] = f[i - 1][f[i - 1][j]];
  118. }
  119. }
  120.  
  121. inline int get_lca(int a, int b){
  122. if(dep[a] > dep[b]) swap(a,b);
  123. if(dep[a] != dep[b]){
  124. for(int i = logn;i >= 0;--i){
  125. if(dep[f[i][b]] >= dep[a]) b = f[i][b];
  126. }
  127. }
  128. if(a == b) return a;
  129. for(int i = logn;i>=0;--i)
  130. if(f[i][a] != f[i][b]) a = f[i][a], b = f[i][b];
  131. return f[0][a];
  132. }
  133.  
  134. inline void Build(){
  135. Tree.build(1, n, root[0]);
  136. dfs(1, 0, 1);
  137. get_ancester();
  138. }
  139.  
  140. inline void Init(){
  141. Read();
  142. Disperse();
  143. Build();
  144. }
  145.  
  146. inline void Work(){
  147.  
  148. int lastans = 0;
  149.  
  150. while(m--){
  151. int u, v, k;
  152. scanf("%d%d%d",&u, &v, &k);
  153. // u ^= lastans;
  154.  
  155. int lca = get_lca(u, v);
  156.  
  157. lastans = Tree.query(1, n, root[u], root[v], root[lca], root[f[0][lca]], k);
  158. lastans = Sorted[lastans];
  159.  
  160. printf("%d\n", lastans);
  161. }
  162. }
  163.  
  164. int main(){
  165. SetIO("input");
  166. Init();
  167. Work();
  168. return 0;
  169. }

  

SP10628 COT - Count on a tree 主席树的更多相关文章

  1. spoj cot: Count on a tree 主席树

    10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...

  2. spoj COT - Count on a tree(主席树 +lca,树上第K大)

    您将获得一个包含N个节点的树.树节点的编号从1到Ñ.每个节点都有一个整数权重. 我们会要求您执行以下操作: uvk:询问从节点u到节点v的路径上的第k个最小权重 输入 在第一行中有两个整数Ñ和中号.( ...

  3. SPOJ Count on a tree(主席树+LCA)

    一.题目 COT - Count on a tree You are given a tree with N nodes. The tree nodes are numbered from 1 to  ...

  4. 【BZOJ-2588】Count on a tree 主席树 + 倍增

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 3749  Solved: 873[ ...

  5. Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...

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

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

  7. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

  8. 洛谷P2633 Count on a tree(主席树上树)

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

  9. 洛谷 P2633 Count on a tree 主席树

    在一棵树上,我们要求点 $(u,v)$ 之间路径的第$k$大数. 对于点 $i$  ,建立 $i$  到根节点的一棵前缀主席树. 简单容斥后不难得出结果为$sumv[u]+sumv[v]−sumv[l ...

随机推荐

  1. 脑图工具MindNode"附属节点"是什么意思 图解

    新手会发现在主节点上无论是按Tab子节点还是按Enter附属节点,都是向右延伸,感觉像没区别? 其实不然,从第二个节点开始,你再按 Tab 或者 Enter 就知道区别了. 废话少说,直接上图. 我觉 ...

  2. 使用 Shiro 设计基于用户、角色、权限的通用权限管理系统

    一.前言 在大型的信息管理系统中,经常涉及到权限管理系统 下面来个 demo,很多复杂的系统的设计都来自它 代码已经放到github上了,地址:https://github.com/larger5/s ...

  3. 边框的使用,border-radius,box-shadow,border-image

    <html>    <head>        <meta charset="UTF-8">        <title></ ...

  4. 一些html5

    ---匿名函数(funcation(){}())---- 一.拖拽 draggable=ture-----A拖动元素上事件 1. 拖拽开始:ondragstart2. 拖拽中:ondrag3. 拖拽结 ...

  5. Codeforces 679A Bear and Prime 100

    链接:传送门 题意:给你一个隐藏数,这个隐藏数在[2,100]之间,现在最多可以询问20次,每次询问的是这个数是不是隐藏数的底数,是为yes,不是为no,每次询问后都需要flush一下输出缓冲区,最后 ...

  6. Eigen下载安装

    首先提供Eigen的两个重要网站 官方网站 下载地址 1.下载 wget http://bitbucket.org/eigen/eigen/get/3.3.5.tar.gz 2.解压缩 tar -zx ...

  7. python--(常用模块-2序列化)

    python--(常用模块-2序列化) 一.序列化: 把对象打散成bytes或者字符串. 方便存储和传输 序列化 把bytes或者字符串转换回对象. 反序列化 # dumps 序列化. 把对象转化成b ...

  8. 洛谷 P1029 最大公约数和最小公倍数问题

    有两种做法 一种是gcd与lcm相乘后就是两个数的乘积,枚举第一个数,算出第二数,看最大公约数是不是题目给的. 第二种就lcm/gcd的答案为两个互质的数相乘.然后就枚举有多少组互质的数相乘等于lcm ...

  9. tcpdump的使用以及参数详解

    平时分析客户端和服务器网络交互的问题时,很多情况下需要在客户端和服务器抓包分析报文.一般win下抓包使用WireShark即可,但是linux下就需要用到tcpdump了,下面是一些对于tcpdump ...

  10. 【 【henuacm2016级暑期训练】动态规划专题 K】 Really Big Numbers

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 会发现如果x是reallynumber那么x+1也会是reallynumber.... (个位数+1,各位数的和+1了但是整个数也+ ...