题解

真真正正是个码农题,不过很套路,熟练就打得很快,不过要用点维护边的信息在 \(\text{LCA}\) 出要注意,不能处理此点的信息

\(Code\)

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstring>
  4. using namespace std;
  5. const int N = 2e5 + 5;
  6. int n, m, h[N];
  7. struct edge{int to, nxt, w, id;}e[N << 1];
  8. inline void add(int u, int v, int w, int id)
  9. {
  10. static int tot = 0;
  11. e[++tot] = edge{v, h[u], w, id}, h[u] = tot;
  12. }
  13. int top[N], fa[N], dfn[N], dep[N], siz[N], son[N], ver[N], edg[N];
  14. void dfs1(int x)
  15. {
  16. siz[x] = 1;
  17. for(register int i = h[x]; i; i = e[i].nxt)
  18. {
  19. int v = e[i].to;
  20. if (v == fa[x]) continue;
  21. edg[v] = e[i].w, ver[e[i].id] = v, fa[v] = x, dep[v] = dep[x] + 1, dfs1(v), siz[x] += siz[v];
  22. if (siz[v] > siz[son[x]]) son[x] = v;
  23. }
  24. }
  25. void dfs2(int x)
  26. {
  27. static int dfc = 0;
  28. dfn[x] = ++dfc;
  29. if (son[x]) top[son[x]] = top[x], dfs2(son[x]);
  30. for(register int i = h[x]; i; i = e[i].nxt)
  31. {
  32. int v = e[i].to;
  33. if (v == fa[x] || v == son[x]) continue;
  34. top[v] = v, dfs2(v);
  35. }
  36. }
  37. struct Tree{
  38. #define ls (p << 1)
  39. #define rs (ls | 1)
  40. const int INF = 0x3f3f3f3f;
  41. int sum[N << 2], mn[N << 2], mx[N << 2], tag[N << 2];
  42. inline Tree(){memset(mn, 0x3f3f3f3f, sizeof mn), memset(mx, -0x3f3f3f3f, sizeof mx);}
  43. void change(int p){sum[p] *= -1, mx[p] *= -1, mn[p] *= -1, swap(mx[p], mn[p]), tag[p] ^= 1;}
  44. void pushup(int p){sum[p] = sum[ls] + sum[rs], mn[p] = min(mn[ls], mn[rs]), mx[p] = max(mx[ls], mx[rs]);}
  45. void pushdown(int p)
  46. {
  47. if (!tag[p]) return;
  48. change(ls), change(rs), tag[p] ^= 1;
  49. }
  50. void update_node(int p, int l, int r, int x, int v)
  51. {
  52. if (l == r)
  53. {
  54. sum[p] = mn[p] = mx[p] = v;
  55. if (l == 1) mn[p] = INF, mx[p] = -INF;
  56. return;
  57. }
  58. pushdown(p);
  59. int mid = (l + r) >> 1;
  60. if (x <= mid) update_node(ls, l, mid, x, v);
  61. else update_node(rs, mid + 1, r, x, v);
  62. pushup(p);
  63. }
  64. void update_rev(int p, int l, int r, int x, int y)
  65. {
  66. if (x <= l && r <= y) return void(change(p));
  67. pushdown(p);
  68. int mid = (l + r) >> 1;
  69. if (x <= mid) update_rev(ls, l, mid, x, y);
  70. if (y > mid) update_rev(rs, mid + 1, r, x, y);
  71. pushup(p);
  72. }
  73. inline void tree_rev(int x, int y)
  74. {
  75. int fx = top[x], fy = top[y];
  76. while (fx ^ fy)
  77. {
  78. if (dep[fx] > dep[fy]) update_rev(1, 1, n, dfn[fx], dfn[x]), x = fa[fx], fx = top[x];
  79. else update_rev(1, 1, n, dfn[fy], dfn[y]), y = fa[fy], fy = top[y];
  80. }
  81. if (dep[x] > dep[y]) swap(x, y);
  82. if (x == y) return;
  83. update_rev(1, 1, n, dfn[x] + 1, dfn[y]);
  84. }
  85. int query_sum(int p, int l, int r, int x, int y)
  86. {
  87. if (x <= l && r <= y) return sum[p];
  88. pushdown(p);
  89. int mid = (l + r) >> 1, ret = 0;
  90. if (x <= mid) ret += query_sum(ls, l, mid, x, y);
  91. if (y > mid) ret += query_sum(rs, mid + 1, r, x, y);
  92. return ret;
  93. }
  94. inline int tree_sum(int x, int y)
  95. {
  96. int fx = top[x], fy = top[y], ret = 0;
  97. while (fx ^ fy)
  98. {
  99. if (dep[fx] > dep[fy]) ret += query_sum(1, 1, n, dfn[fx], dfn[x]), x = fa[fx], fx = top[x];
  100. else ret += query_sum(1, 1, n, dfn[fy], dfn[y]), y = fa[fy], fy = top[y];
  101. }
  102. if (dep[x] > dep[y]) swap(x, y);
  103. if (x == y) return ret;
  104. return ret + query_sum(1, 1, n, dfn[x] + 1, dfn[y]);
  105. }
  106. int query_max(int p, int l, int r, int x, int y)
  107. {
  108. if (x <= l && r <= y) return mx[p];
  109. pushdown(p);
  110. int mid = (l + r) >> 1, ret = -INF;
  111. if (x <= mid) ret = max(ret, query_max(ls, l, mid, x, y));
  112. if (y > mid) ret = max(ret, query_max(rs, mid + 1, r, x, y));
  113. return ret;
  114. }
  115. inline int tree_max(int x, int y)
  116. {
  117. int fx = top[x], fy = top[y], ret = -INF;
  118. while (fx ^ fy)
  119. {
  120. if (dep[fx] > dep[fy]) ret = max(ret, query_max(1, 1, n, dfn[fx], dfn[x])), x = fa[fx], fx = top[x];
  121. else ret = max(ret, query_max(1, 1, n, dfn[fy], dfn[y])), y = fa[fy], fy = top[y];
  122. }
  123. if (dep[x] > dep[y]) swap(x, y);
  124. if (x == y) return ret;
  125. return max(ret, query_max(1, 1, n, dfn[x] + 1, dfn[y]));
  126. }
  127. int query_min(int p, int l, int r, int x, int y)
  128. {
  129. if (x <= l && r <= y) return mn[p];
  130. pushdown(p);
  131. int mid = (l + r) >> 1, ret = INF;
  132. if (x <= mid) ret = min(ret, query_min(ls, l, mid, x, y));
  133. if (y > mid) ret = min(ret, query_min(rs, mid + 1, r, x, y));
  134. return ret;
  135. }
  136. inline int tree_min(int x, int y)
  137. {
  138. int fx = top[x], fy = top[y], ret = INF;
  139. while (fx ^ fy)
  140. {
  141. if (dep[fx] > dep[fy]) ret = min(ret, query_min(1, 1, n, dfn[fx], dfn[x])), x = fa[fx], fx = top[x];
  142. else ret = min(ret, query_min(1, 1, n, dfn[fy], dfn[y])), y = fa[fy], fy = top[y];
  143. }
  144. if (dep[x] > dep[y]) swap(x, y);
  145. if (x == y) return ret;
  146. return min(ret, query_min(1, 1, n, dfn[x] + 1, dfn[y]));
  147. }
  148. }seg;
  149. int main()
  150. {
  151. scanf("%d", &n);
  152. for(register int i = 1, u, v, w; i < n; i++)
  153. scanf("%d%d%d", &u, &v, &w), ++u, ++v, add(u, v, w, i), add(v, u, w, i);
  154. dfs1(1), top[1] = 1, dfs2(1);
  155. for(register int i = 1; i <= n; i++) seg.update_node(1, 1, n, dfn[i], edg[i]);
  156. scanf("%d", &m);
  157. char op[5];
  158. for(int u, v; m; --m)
  159. {
  160. scanf("%s%d%d", op, &u, &v), ++u, ++v;
  161. if (op[0] == 'C') seg.update_node(1, 1, n, dfn[ver[u - 1]], v - 1);
  162. else if (op[0] == 'N') seg.tree_rev(u, v);
  163. else if (op[0] == 'S') printf("%d\n", seg.tree_sum(u, v));
  164. else if (op[1] == 'A') printf("%d\n", seg.tree_max(u, v));
  165. else printf("%d\n", seg.tree_min(u, v));
  166. }
  167. }

Luogu P1505.[国家集训队]旅游的更多相关文章

  1. LUOGU P1505 [国家集训队]旅游 (树链剖分+线段树)

    传送门 解题思路 快被调死的码农题,,,其实就是一个边权下放到点权的线段树+树剖. #include<iostream> #include<cstdio> #include&l ...

  2. 洛谷 P1505 [国家集训队]旅游 解题报告

    P1505 [国家集训队]旅游 题目描述 \(\tt{Ray}\) 乐忠于旅游,这次他来到了\(T\)城.\(T\)城是一个水上城市,一共有 \(N\) 个景点,有些景点之间会用一座桥连接.为了方便游 ...

  3. 洛谷 P1505 [国家集训队]旅游 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1505 [国家集训队]旅游 题目描述 Ray 乐 ...

  4. 2018.06.29 洛谷P1505 [国家集训队]旅游(树链剖分)

    旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有 ...

  5. P1505 [国家集训队]旅游

    \(\color{#0066ff}{题 目 描 述}\) Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了 ...

  6. 洛谷P1505 [国家集训队]旅游

    题目描述 \(Ray\) 乐忠于旅游,这次他来到了\(T\) 城.\(T\) 城是一个水上城市,一共有 \(N\) 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,\(T ...

  7. P1505 [国家集训队]旅游[树剖]

    题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路 ...

  8. 洛谷P1505 [国家集训队]旅游(树剖+线段树)

    传送门 这该死的码农题…… 把每一条边变为它连接的两个点中深度较浅的那一个,然后就是一堆单点修改/路径查询,不讲了 这里就讲一下怎么搞路径取反,只要打一个标记就好了,然后把区间和取反,最大最小值交换然 ...

  9. [洛谷]P1505 [国家集训队]旅游

    题目链接: 传送门 题目分析: 树剖板,支持单点修改,区间取反,区间求最大值/最小值/和 区间取反取两次等于没取,维护一个\(rev\ tag\),每次打标记用\(xor\)打,记录是否需要翻转,\( ...

  10. luoguP1505 [国家集训队]旅游(真的毒瘤)

    luogu P1505 [国家集训队]旅游 题目 #include<iostream> #include<cstdio> #include<cstdlib> #in ...

随机推荐

  1. Idea中Git的常用操作及可能存在的问题

    一.使用 1.从git上下载项目 (1)默认branch下载(pull) (2)指定branch下载 (3)克隆远程仓库到本地(git clone) git clone https://github. ...

  2. Selenium4+Python3系列(十一) - Page Factory设计模式

    写在前面: Page Object模式,目的是将元素定位和元素操作分层,只接触测试内容,不写基础内容,便于后续对自动化测试用例体系的维护,这是中心思想,也是核心. 那么我们继续将简洁延续,这里沿用Ja ...

  3. bug处理记录:Error running 'WorkflowApplication': Command line is too long. Shorten command line for WorkflowApplication or also for Spring Boot default configuration?

    1.报错信息 Error running 'WorkflowApplication': Command line is too long. Shorten command line for Workf ...

  4. 回溯法求解n皇后问题(复习)

    回溯法 回溯法是最常用的解题方法,有"通用的解题法"之称.当要解决的问题有若干可行解时,则可以在包含问题所有解的空间树中,按深度优先的策略,从根节点出发搜索解空间树.算法搜索至解空 ...

  5. 精华推荐 |【深入浅出Sentinel原理及实战】「原理探索专题」完整剖析Alibaba微服务架构体系之轻量级高可用流量控制组件Sentinel(1)

    Sentinel是什么?不要概念混淆啊! 注意:本Sentinel与Redis服务Sentinel是两回事,压根不是一个概念,请大家不要混肴. Alibaba的Sentinel Sentinel是由阿 ...

  6. last-child可能你也会踩的坑

    旧文章从语雀迁移过来,原日期为2021-07-14 问题 当时写在写一个列表,列表每一项需要下面加下划线,最后一项不加下划线.第一时间,想到使用 :``last-child 这个伪类来实现. 当时的代 ...

  7. Solon Java Framework v1.12.0 发布

    一个更现代感的 Java 应用开发框架:更快.更小.更自由.没有 Spring,没有 Servlet,没有 JavaEE:独立的轻量生态.主框架仅 0.1 MB. @Controller public ...

  8. [OpenCV实战]7 使用YOLOv3和OpenCV进行基于深度学习的目标检测

    目录 1 YOLO介绍 1.1 YOLOv3原理 1.2 为什么要将OpenCV用于YOLO? 1.3 在Darknet和OpenCV上对YOLOv3进行速度测试 2 使用YOLOv3进行对象检测(C ...

  9. python进阶之路9文件的处理方法

    内容回顾 字典内置方法 1.类型转换 dict() 2.重要操作 get() d[key] = values 常用 pop() update() 键存在则修改键值对 键不存在则新增键值对 fromke ...

  10. 阿里云kafka使用记录(python版本)

    kafka端   consumer vpc版代码   import socket from kafka import KafkaConsumer from kafka.errors import Ka ...