题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3078

题意: 给出一棵 n 个点的带点权值的树, 接下来有 q 组形如 k, x, y 的输入, 若 k == 0 则将 x 点的权值替换成 y, 否则输出 x 到 y 之间顶点地 k 大的权值.

思路: 用一个数组 val 记录一下每个顶点的权值, 对于k == 0, 直接令 val[x] = y 即可 .

对于询问, 可以先求出 lca, 再记录一下路径上的顶点的权值, sort 一下, 输出第 k 大的即可.

代码:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <algorithm>
  6. #include <vector>
  7. using namespace std;
  8.  
  9. const int MAXN = 8e4 + ;
  10. vector<int> vt[MAXN];
  11. int dp[MAXN << ][];
  12. int first[MAXN], ver[MAXN << ], deep[MAXN << ];
  13. int pre[MAXN], val[MAXN], yy[MAXN], ip = , indx = ;
  14.  
  15. bool cmp(int x, int y){
  16. return x > y;
  17. }
  18.  
  19. void dfs(int u, int h, int fa){
  20. pre[u] = fa;
  21. ver[++indx] = u;
  22. deep[indx] = h;
  23. first[u] = indx;
  24. for(int i = ; i < vt[u].size(); i++){
  25. int v = vt[u][i];
  26. if(v != fa){
  27. dfs(v, h + , u);
  28. ver[++indx] = u;
  29. deep[indx] = h;
  30. }
  31. }
  32. }
  33.  
  34. void ST(int n){
  35. for(int i = ; i <= n; i++){
  36. dp[i][] = i;
  37. }
  38. for(int j = ; ( << j) <= n; j++){
  39. for(int i = ; i + ( << j) - <= n; i++){
  40. int x = dp[i][j - ], y = dp[i + ( << (j - ))][j -];
  41. dp[i][j] = deep[x] < deep[y] ? x : y;
  42. }
  43. }
  44. }
  45.  
  46. int RMQ(int l, int r){
  47. int len = log2(r - l + );
  48. int x = dp[l][len], y = dp[r - ( << len) + ][len];
  49. return deep[x] < deep[y] ? x : y;
  50. }
  51.  
  52. int LCA(int x, int y){
  53. int l = first[x];
  54. int r = first[y];
  55. if(l > r) swap(l, r);
  56. int pos = RMQ(l, r);
  57. return ver[pos];
  58. }
  59.  
  60. void path(int x, int root, int &pos){
  61. while(x != root && x != -){
  62. yy[pos++] = val[x];
  63. x = pre[x];
  64. }
  65. }
  66.  
  67. void solve(int x, int y, int k){
  68. int pos = , lca = LCA(x, y);
  69. path(x, lca, pos);
  70. path(y, lca, pos);
  71. yy[pos++] = val[lca];
  72. if(pos < k) puts("invalid request!");
  73. else{
  74. sort(yy, yy + pos, cmp);//注意是从大到小的第 k 大!!!!!!!!!
  75. printf("%d\n", yy[k - ]);
  76. }
  77. }
  78.  
  79. int main(void){
  80. int n, q, x, y, op;
  81. scanf("%d%d", &n, &q);
  82. for(int i = ; i <= n; i++){
  83. scanf("%d", &val[i]);
  84. }
  85. for(int i = ; i < n; i++){
  86. scanf("%d%d", &x, &y);
  87. vt[x].push_back(y);
  88. vt[y].push_back(x);
  89. }
  90. dfs(, , -);
  91. ST(indx);
  92. while(q--){
  93. scanf("%d%d%d", &op, &x, &y);
  94. if(!op) val[x] = y;
  95. else solve(x, y, op);
  96. }
  97. return ;
  98. }

hdu3078(lca / RMQ在线)的更多相关文章

  1. zoj3195(lca / RMQ在线)

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3195 题意: 给出一棵 n 个节点的带边权的树, 有 q 组形 ...

  2. hdu 3078(LCA的在线算法)

    Network Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  3. 【Homework】LCA&RMQ

    我校是神校,作业竟然选自POJ,难道不知道“珍爱生命 勿刷POJ”么? 所有注明模板题的我都十分傲娇地没有打,于是只打了6道题(其实模板题以前应该打过一部分但懒得找)(不过感觉我模板还是不够溜要找个时 ...

  4. POJ 2763 (LCA +RMQ+树状数组 || 树链部分) 查询两点距离+修改边权

    题意: 知道了一颗有  n 个节点的树和树上每条边的权值,对应两种操作: 0 x        输出 当前节点到 x节点的最短距离,并移动到 x 节点位置 1 x val   把第 x 条边的权值改为 ...

  5. 算法详解(LCA&RMQ&tarjan)补坑啦!完结撒花(。◕ˇ∀ˇ◕)

    首先,众所周知,求LCA共有3种算法(树剖就不说了,太高级,以后再学..). 1.树上倍增(ST表优化) 2.RMQ&时间戳(ST表优化) 3.tarjan(离线算法)不讲..(后面补坑啦!) ...

  6. LCA最近公共祖先 ST+RMQ在线算法

    对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决.     这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...

  7. HDU 2586 How far away ?(经典)(RMQ + 在线ST+ Tarjan离线) 【LCA】

    <题目链接> 题目大意:给你一棵带有边权的树,然后进行q次查询,每次查询输出指定两个节点之间的距离. 解题分析:本题有多重解决方法,首先,可用最短路轻易求解.若只用LCA解决本题,也有三种 ...

  8. Tourists Gym - 101002I LCA——dfs+RMQ在线算法

    LCA(Least Common Ancestors),即最近公共祖先,是指这样一个问题:在有根树中,找出某两个结点u和v最近的公共祖先(另一种说法,离树根最远的公共祖先). 知识需求:1)RMQ的S ...

  9. hdu2874(lca / tarjan离线 + RMQ在线)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2874 题意: 给出 n 个顶点 m 条边的一个森林, 有 k 个形如 x y 的询问, 输出 x, ...

随机推荐

  1. unity3D中一些有用的设置

    edit-project setting-time:可以设置fixed update()每一帧执行的时间 timescale:时间流动速度,设置为0则运用了time.deltatime的动画计时器均停 ...

  2. hdu 1864 最大报销额(01背包)

    最大报销额 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  3. codeforces 632A A. Grandma Laura and Apples(暴力)

    A. Grandma Laura and Apples time limit per test 1 second memory limit per test 256 megabytes input s ...

  4. stl_set.h

    stl_set.h // Filename: stl_set.h // Comment By: 凝霜 // E-mail: mdl2009@vip.qq.com // Blog: http://blo ...

  5. Convolutional Neural Networks for Visual Recognition 2

    Linear Classification 在上一讲里,我们介绍了图像分类问题以及一个简单的分类模型K-NN模型,我们已经知道K-NN的模型有几个严重的缺陷,第一就是要保存训练集里的所有样本,这个比较 ...

  6. bzoj1000~1025

    以后还是这样 25道题一起发 看着爽 noip失利之后发粪涂墙 刷了一波bzoj 题解: bzoj1000 A+B问题 这题不同的人有不同的写法,我写了个线段树套Treap,应该还是挺简单的 但是看别 ...

  7. bzoj 3221: Obserbing the tree树上询问 树链剖分+线段树

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3221 题解 啊呀...这是昨天的考试题啊...直接就粘了.. 与4515: [Sdoi2 ...

  8. 使用NSURLProtocol和NSURLSession拦截UIWebView的HTTP请求(包括ajax请求)

    问题:服务器端有一个网站需要AD认证,整站都开了Basic认证,包括图片,CSS等资源,我在HTTP请求头里面添加认证所需的用户名和密码,传递到服务器端可以认证通过.我在UIWebView的shoul ...

  9. 浅谈双流水线调度问题以及Jhonson算法

    引入:何为流水线问题 有\(n\)个任务,对于每个任务有\(m\)道工序,每个任务的\(m\)道工序必须在不同的m台机器上依次完成才算把这个任务完成,在前\(i-1\)道工序完成后才能去完成第\(i\ ...

  10. 使用Sed抽取MySQL安装文档的目录及行号

    sed -nr  -e '/^2.|^shell/=' -e '/^2.|^shell/p' INSTALL-SOURCE |awk '{if (NR%2==1) x=$1; else printf ...