这题是裸的主席树,每个节点建一棵主席树,再加个lca就可以了。

  历尽艰辛,终于A掉了这一题,这般艰辛也显示出了打代码的不熟练。

  错误:1、lca倍增的时候i和j写反了,RE了5次,实在要吸取教训

     2、主席树插入操作的时候,如果插入到的那个点(叶节点)原来有值,而没有加上,导致了WA

  以下是历尽艰辛的代码,还很长。

 

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <algorithm>
  4. #include <queue>
  5. #include <map>
  6.  
  7. using namespace std;
  8.  
  9. const int maxn = ;
  10. int n, m, w[maxn];
  11. int head[maxn], label;
  12. struct Edge
  13. {
  14. int v, next;
  15. Edge (int v = , int next = ):
  16. v(v), next(next) {}
  17. }e[maxn*];
  18. int depth[maxn], f[maxn][], root[maxn], temp[maxn], s_num;
  19. queue <int> q;
  20. map <int, int> id;
  21. struct Tree
  22. {
  23. int sum[maxn*], ls[maxn*], rs[maxn*], cnt;
  24. Tree ()
  25. {
  26. sum[] = , cnt = ;
  27. }
  28. void PushUp(int rt)
  29. {
  30. sum[rt] = sum[ls[rt]]+sum[rs[rt]];
  31. }
  32. void insert(int las_rt, int rt, int l, int r, int p, int d)
  33. {
  34. if (l == r)
  35. {
  36. sum[rt] = sum[las_rt]+d;
  37. return ;
  38. }
  39. int mid = (l+r)>>;
  40. if (p <= mid)
  41. {
  42. ls[rt] = ++cnt, rs[rt] = rs[las_rt];
  43. insert(ls[las_rt], ls[rt], l, mid, p, d);
  44. }
  45. else
  46. {
  47. ls[rt] = ls[las_rt], rs[rt] = ++cnt;
  48. insert(rs[las_rt], rs[rt], mid+, r, p, d);
  49. }
  50. PushUp(rt);
  51. }
  52. int query(int u_rt, int v_rt, int lca_rt, int lca_pos, int l, int r, int k)
  53. {
  54. if (l == r)
  55. return l;
  56. int mid = (l+r)>>;
  57. int s_l = sum[ls[u_rt]]+sum[ls[v_rt]]-*sum[ls[lca_rt]]+(lca_pos >= l && lca_pos <= mid);
  58. if (k <= s_l)
  59. return query(ls[u_rt], ls[v_rt], ls[lca_rt], lca_pos, l, mid, k);
  60. else
  61. return query(rs[u_rt], rs[v_rt], rs[lca_rt], lca_pos, mid+, r, k-s_l);
  62. }
  63. }T;
  64.  
  65. void ins(int u, int v)
  66. {
  67. e[++label] = Edge(v, head[u]);
  68. head[u] = label;
  69. }
  70.  
  71. void in()
  72. {
  73. scanf("%d %d", &n, &m);
  74. for (int i = ; i <= n; ++i)
  75. scanf("%d", &w[i]);
  76. for (int i = ; i <= n; ++i)
  77. head[i] = -;
  78. label = -;
  79. for (int i = ; i < n; ++i)
  80. {
  81. int u, v;
  82. scanf("%d %d", &u, &v);
  83. ins(u, v), ins(v, u);
  84. }
  85. }
  86.  
  87. void Build_lca()
  88. {
  89. for (int i = ; i <= ; ++i)
  90. for (int j = ; j <= n; ++j)
  91. f[j][i] = -;
  92. q.push();
  93. depth[] = ;
  94. f[][] = -;
  95. while (!q.empty())
  96. {
  97. int u = q.front();
  98. for (int i = head[u]; i != -; i = e[i].next)
  99. {
  100. int v = e[i].v;
  101. if (v == f[u][])
  102. continue ;
  103. f[v][] = u;
  104. depth[v] = depth[u]+;
  105. q.push(v);
  106. }
  107. q.pop();
  108. }
  109. for (int i = ; i <= ; ++i)
  110. for (int j = ; j <= n; ++j)
  111. {
  112. if (f[j][i-] == -)
  113. continue ;
  114. f[j][i] = f[f[j][i-]][i-];
  115. }
  116. }
  117.  
  118. void Hash_a()
  119. {
  120. for (int i = ; i <= n; ++i)
  121. temp[i] = w[i];
  122. sort(temp+, temp+n+);
  123. s_num = ;
  124. for (int i = ; i <= n; ++i)
  125. if (temp[i] != temp[i-] || i == )
  126. {
  127. temp[++s_num] = temp[i];
  128. id[temp[i]] = s_num;
  129. }
  130. }
  131.  
  132. void dfs(int u)
  133. {
  134. root[u] = ++T.cnt;
  135. T.insert(u == ? : root[f[u][]], root[u], , s_num, id[w[u]], );
  136. for (int i = head[u]; i != -; i = e[i].next)
  137. {
  138. int v = e[i].v;
  139. if (v == f[u][])
  140. continue ;
  141. dfs(v);
  142. }
  143. }
  144.  
  145. void Build_tree()
  146. {
  147. Hash_a();
  148. dfs();/*
  149. for (int i = 1; i <= n; ++i)
  150. printf("%d %d\n", i, T.sum[root[i]]);*/
  151. }
  152.  
  153. void prepare()
  154. {
  155. Build_lca();
  156. Build_tree();
  157. }
  158.  
  159. int lca(int u, int v)
  160. {
  161. if (depth[u] < depth[v])
  162. swap(u, v);
  163. for (int i = ; i >= ; --i)
  164. {
  165. if (f[u][i] == -)
  166. continue ;
  167. if (depth[f[u][i]] >= depth[v])
  168. {
  169. u = f[u][i];
  170. if (depth[u] == depth[v])
  171. break ;
  172. }
  173. }
  174. if (u == v)
  175. return u;
  176. for (int i = ; i >= ; --i)
  177. {
  178. if (f[u][i] == -)
  179. continue ;
  180. if (f[u][i] != f[v][i])
  181. {
  182. u = f[u][i];
  183. v = f[v][i];
  184. }
  185. }
  186. return f[u][];
  187. }
  188.  
  189. void work()
  190. {
  191. prepare();
  192. while (m --)
  193. {
  194. int u, v, k;
  195. scanf("%d %d %d", &u, &v, &k);
  196. int t = lca(u, v);
  197. int pos = T.query(root[u], root[v], root[t], id[w[t]], , s_num, k);
  198. printf("%d\n", temp[pos]);
  199. }
  200. }
  201.  
  202. int main()
  203. {
  204. in();
  205. work();
  206. return ;
  207. }

  

SPOJ 10628. SPOJ COT Count on a tree 可持久化线段树的更多相关文章

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

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

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

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

  3. SPOJ 10628 COT - Count on a tree(在树上建立主席树)(LCA)

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

  4. SPOJ - COT Count on a tree

    地址:http://www.spoj.com/problems/COT/en/ 题目: COT - Count on a tree #tree You are given a tree with N  ...

  5. 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree

    题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...

  6. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

  7. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

  8. 「SP10628 COT - Count on a tree」

    主席树的综合运用题. 前置芝士 可持久化线段树:其实就是主席树了. LCA:最近公共祖先,本题需要在\(\log_2N\)及以内的时间复杂度内解决这个问题. 具体做法 主席树维护每个点到根节点这一条链 ...

  9. SPOJ Meteors - 可持久化线段树 - 二分法

    Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby galaxy. The plan ...

随机推荐

  1. hdu 5373 The shortest problem(杭电多校赛第七场)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5373 The shortest problem Time Limit: 3000/1500 MS (J ...

  2. html中去掉文本框(input type="text")的边框或只显示下边框

    去掉: <input   type="text"   name="textfield"   style="border:0px;"&g ...

  3. C# 加密解密以及sha256不可逆加密案例

    class Program { static void Main(string[] args) { string aa = "身份证"; string bb = "key ...

  4. Deep Learning基础--SVD奇异值分解

    矩阵奇异值的物理意义是什么?如何更好地理解奇异值分解?下面我们用图片的例子来扼要分析. 矩阵的奇异值是一个数学意义上的概念,一般是由奇异值分解(Singular Value Decomposition ...

  5. 头像截图上传三种方式之一(一个简单易用的flash插件)(asp.net版本)

    flash中有版权声明,不适合商业开发.这是官网地址:http://www.hdfu.net/ 本文参考了http://blog.csdn.net/yafei450225664/article/det ...

  6. centos7安装完成后的一些配置

    1.打开终端 输入 sudo yum -y update 先更新软件包 2.这是输入语言 应用程序->系统工具->设置->区域和语言->+   ->汉语(中国)-> ...

  7. PTP简介

    PTP简介 在通信网络中,许多业务的正常运行都要求网络时钟同步,即整个网络各设备之间的时间或频率差保持在合理的误差水平内.网络时钟同步包括以下两个概念: l              时间同步:也叫相 ...

  8. Jmeter中的变量(三)

    变量(Variables) Jmeter中的变量(参数化)目的是为了提供改变请求变化的机制.比如登录场景,一般不能使用同一个账号做并发操作. 变量的特点 1) JMeter变量对于测试线程而言是局部变 ...

  9. Makefile的使用方法

    转自:http://blog.chinaunix.net/uid-403164-id-2407545.html 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Wind ...

  10. MVC 之AjaxHelper

    http://www.cnblogs.com/jyan/archive/2012/07/23/2604958.html 除了传统的Ajax方法之外,MVC提供了AjaxHelper类: Helper ...