题目

SP375 QTREE - Query on a tree

解析

也就是个蓝题,因为比较长

树剖裸题(基本上),单点修改,链上查询。

顺便来说一下链上操作时如何将边上的操作转化为点上的操作:

可以看到这个题然我们对边进行操作,我们的树剖是对节点进行操作的,所以我们考虑把边权变为点权。



发现我们节点的点权是连向它的边的边权,所以我们要操作边权的话,我们操作的实际上是其连向点的点权,

假设我们要修改1-4之间的这两条边



我们修改的实际上就是这2,4两个点



我们节点的点权为其父节点连向它的边的边权,所以我们链上修操作的时候,不要操作深度较低的节点,因为它代表的边是它的父节点连向它的那一条,不是要操作的两点之间的边,就像上图我们不操作1号节点一样。

不用特意判断;两个位置的深浅,树剖中会判断,详见这里

再说一下这个题的修改,因为我们是要修改边权,我们的边权给了点,所以我们找一下这条边连的两个点,判断两个点的深度,较深的那个是我们要修改的点。

然后这是SPOJ上的题,我不知道为啥我写c++会挂,经king丨帝御威大佬的指点才用c过的,%%%

代码

  1. #include <ctype.h>
  2. #include <stdio.h>
  3. #include <limits.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #define lson rt << 1
  7. #define rson rt << 1 | 1
  8. #define N 10007
  9. int t, n, m, num, cnt;
  10. int head[N], a[N], w[N], son[N], size[N], f[N], top[N], dep[N], id[N], mx[N << 2];
  11. class node {
  12. public :
  13. int nx, v, w;
  14. } e[N << 2];
  15. void add(int u, int v, int w) {
  16. e[++num].nx = head[u], e[num].v = v, e[num].w = w, head[u] = num;
  17. }
  18. int max(int a, int b) { return a > b ? a : b; }
  19. #define swap(A, B) \
  20. { \
  21. int __T = A; \
  22. A = B; \
  23. B = __T; \
  24. }
  25. void dfs1(int u, int fa) {
  26. size[u] = 1;
  27. for (int i = head[u]; ~i; i = e[i].nx) {
  28. int v = e[i].v;
  29. if (v != fa) {
  30. dep[v] = dep[u] + 1;
  31. f[v] = u;
  32. w[v] = e[i].w; //边权赋给点
  33. dfs1(v, u);
  34. size[u] += size[v];
  35. if (size[v] > size[son[u]]) son[u] = v;
  36. }
  37. }
  38. }
  39. void dfs2(int u, int t) {
  40. id[u] = ++cnt;
  41. a[cnt] = w[u];
  42. top[u] = t;
  43. if (son[u]) dfs2(son[u], t);
  44. for (int i = head[u]; ~i; i = e[i].nx) {
  45. int v = e[i].v;
  46. if (v != f[u] && v != son[u]) dfs2(v, v);
  47. }
  48. }
  49. void pushup(int rt) {
  50. mx[rt] = max(mx[lson], mx[rson]);
  51. }
  52. void build(int l, int r, int rt) {
  53. if (l == r) {
  54. mx[rt] = a[l];
  55. return ;
  56. }
  57. int m = (l + r) >> 1;
  58. build(l, m, lson);
  59. build(m + 1, r, rson);
  60. pushup(rt);
  61. }
  62. void update(int L, int c, int l, int r, int rt) {
  63. if (l == r) {
  64. mx[rt] = c;
  65. return ;
  66. }
  67. int m = (l + r) >> 1;
  68. if (L <= m) update(L, c, l, m, lson);
  69. else update(L, c, m + 1, r, rson);
  70. pushup(rt);
  71. }
  72. int query(int L, int R, int l, int r, int rt) {
  73. if (L <= l && r <= R) return mx[rt];
  74. int m = (l + r) >> 1, ans = -0x3f3f3f3f;
  75. if (L <= m) ans = max(ans, query(L, R, l, m, lson));
  76. if (R > m) ans = max(ans, query(L, R, m + 1, r, rson));
  77. return ans;
  78. }
  79. int query_chain(int x, int y) {
  80. int fx = top[x], fy = top[y], ans = -0x3f3f3f3f;
  81. while (fx != fy) {
  82. if (dep[fx] < dep[fy]) {
  83. swap(x, y);
  84. swap(fx, fy);
  85. }
  86. ans = max(ans, query(id[fx], id[x], 1, cnt, 1));
  87. x = f[fx], fx = top[x];
  88. }
  89. if (id[x] > id[y]) swap(x, y);
  90. ans = max(ans, query(id[x] + 1, id[y], 1, cnt, 1));
  91. /*在这里注意是id[x]+1->id[y],不要算上深度较浅的点*/
  92. return ans;
  93. }
  94. int main() {
  95. scanf("%d", &t);
  96. while (t -- ) {
  97. num = cnt = 0;
  98. memset(head, -1, sizeof(head));
  99. memset(dep, 0, sizeof(dep));
  100. memset(id, 0, sizeof(id));
  101. memset(a, 0, sizeof(a));
  102. memset(w, 0, sizeof(w));
  103. memset(top, 0, sizeof(top));
  104. memset(size, 0, sizeof(size));
  105. memset(e, 0, sizeof(e));
  106. memset(mx, 0, sizeof(mx));
  107. memset(son, 0, sizeof(son));
  108. memset(f, 0, sizeof(f));
  109. scanf("%d", &n);
  110. for (int i = 1, x, y, z; i < n; ++i) {
  111. scanf("%d%d%d", &x, &y, &z);
  112. add(x, y, z), add(y, x, z);
  113. }
  114. dfs1(1, 0), dfs2(1, 1);
  115. build(1, n, 1);
  116. char s[20];
  117. int x, y;
  118. while (1) {
  119. scanf("%s", s);
  120. if (s[0] == 'D') break;
  121. else if (s[0] == 'C') {
  122. scanf("%d%d", &x, &y);
  123. x = dep[e[x << 1].v] > dep[e[(x << 1) - 1].v] ? e[x << 1].v : e[(x << 1) - 1].v;
  124. /*因为是无向边,加了两次,两次的v都不是一个点*/
  125. update(id[x], y, 1, n, 1);
  126. } else {
  127. scanf("%d%d", &x, &y);
  128. printf("%d\n", query_chain(x, y));
  129. }
  130. }
  131. }
  132. return 0;
  133. }

SP375 QTREE - Query on a tree (树剖)的更多相关文章

  1. SPOJ QTREE Query on a tree 树链剖分+线段树

    题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...

  2. spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)

    传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...

  3. SPOJ QTREE Query on a tree --树链剖分

    题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...

  4. SP375 QTREE - Query on a tree

    题意大意 给定\(n\)个点的树,边按输入顺序编号为\(1,2,...n-1\),要求作以下操作: CHANGE \(i\) \(t_i\) 将第\(i\)条边权值改为\(t_i\),QUERY \( ...

  5. spoj 375 QTREE - Query on a tree 树链剖分

    题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...

  6. SPOJ QTREE Query on a tree ——树链剖分 线段树

    [题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...

  7. QTREE - Query on a tree

    QTREE - Query on a tree 题目链接:http://www.spoj.com/problems/QTREE/ 参考博客:http://blog.sina.com.cn/s/blog ...

  8. SPOJ 375 树链剖分 QTREE - Query on a tree

    人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...

  9. 题解 SP375 【QTREE - Query on a tree】

    \[ \texttt{Preface} \] 这题在 \(\text{Luogu}\) 上竟然不能交 \(C++\) ,会一直 \(Waiting\) ,只能交非 \(C++\) 的语言. 所以打完了 ...

随机推荐

  1. @Autowired和@Resource的区别和联系

    背景: 今天下班路上看到一个大货车,于是想到了装配,然后脑海里跳出了一个注解@Autowired(自动装配),于是又想到最近工作项目用的都是@Resource注解来进行装配.于是本着学什么东西都要一钻 ...

  2. Delaunay和Voronoi

    什么是Delaunay三角剖分? 图1:Delaunay三角剖分偏爱小角度 给定平面中的一组点,三角剖分指的是将平面细分为三角形,这些点为顶点.在图1中,我们在左侧图像上看到了一组地标,在中间图像上看 ...

  3. 华为云ARM64服务器试用

    公司同事弄了个华为云的ARM64服务器,让我帮忙部署我们的服务,所以先试用了一下. 总体感觉还行,使用的CentOS系统,yum也能用,epel源也可以用.但是SCL软件集用不了. uname -a ...

  4. Nginx之Rewrite规则

    IF语句: http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_rewrite_module.html#if 首先申明nginx只有i ...

  5. EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之CDN内容分发网络

    背景分析 EasyDSS流媒体解决方案提供一站式的转码.点播.直播.录像.检索.时移回放服务,极大地简化了开发和集成的工作,并且EasyDSS支持多种特性,完全能够满足企业视频信息化建设方面的需求.其 ...

  6. photoshop7.0 排版一寸照片、2寸照片

    说明:必须先照一张一寸电子照片,否则是无法做成 1.本例同样采用photoshop CS5制作,其它版本通用,这里采用上一教程“PS照片处理教程-制作一寸照片并排版”的处理效果图进行排版,首先在PS中 ...

  7. SecureCRT-登录unix/linux服务器主机的软件

    百度百科说辞: SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件. SecureCRT支持SSH,同时支持Te ...

  8. linux内存管理swap分区

    一.什么是linux的内存机制? 我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概念. 物 ...

  9. spring boot实现切割分片上传

    文件上传是web开发中经常会遇到的 springboot的默认配置为10MB,大于10M的是传不上服务器的,需要修改默认配置 但是如果修改支持大文件又会增加服务器的负担. 当文件大于一定程度时,不仅服 ...

  10. ES6学习小结

    ES6(ES2015)--IE10+.Chrome.FireFox.移动端.NodeJS 编译.转换 1.在线转换 2.提前编译 babel = browser.js ES6: 1.变量 var 重复 ...