两个更新操作,一个将第i条路径权值改为w,一个是将a-b之间所有路径权值取反。

一个查询操作,求a-b之间路径中权值最大的边。

很容易想到维护一个最大最小值,取反就是把最大最小取反交换一下。

开始遇到一个问题就是我把根节点赋值0,上一道题求和没问题,但是这道题会出问题,于是线段树建树的时候从2开始建的,第一次尝试这么写,不过也没什么问题。

wa了一天。。。。

一开始的错是pushdown的时候没有把子节点的fg更新,于是我改了fg[lson]=fg[rson]=1。。。。。。。。

就这样。。。。我对着这份代码看了几个小时。。。。。找数据。。。后来自己写了发对拍。。。。
后来终于忍不了了。。。。找了别人的代码。。。。

哦,应该是fg[lson] ^= 1;  fg[rson] ^= 1;

我果然不会线段树。。。。。

mdzz

  1. #include <algorithm>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <iostream>
  5. using namespace std;
  6. const int N = ;
  7.  
  8. //
  9. struct Edge {
  10. int to, next, cost, id;
  11. } edge[N*];
  12. int head[N], cntE;
  13. void addedge(int u, int v, int w, int id) {
  14. edge[cntE].to = v; edge[cntE].next = head[u]; edge[cntE].cost = w; edge[cntE].id = id; head[u] = cntE++;
  15. edge[cntE].to = u; edge[cntE].next = head[v]; edge[cntE].cost = w; edge[cntE].id = id; head[v] = cntE++;
  16. }
  17. //
  18. int dep[N], sz[N], fa[N], son[N], son_cost[N];
  19. int road[N];
  20. void dfs1(int u, int par, int d) {
  21. dep[u] = d; sz[u] = ; fa[u] = par;
  22. for (int i = head[u]; ~i; i = edge[i].next) {
  23. int v = edge[i].to;
  24. if (v != par) {
  25. road[edge[i].id] = v;
  26. dfs1(v, u, d+);
  27. sz[u] += sz[v];
  28. if (son[u] == - || sz[v] > sz[son[u]]) {
  29. son[u] = v;
  30. son_cost[u] = edge[i].cost;
  31. }
  32. }
  33. }
  34. }
  35. int top[N], dfn[N], rk[N], idx;
  36. int a[N];
  37. void dfs2(int u, int rt, int cost) {
  38. top[u] = rt; dfn[u] = ++idx; a[idx] = cost;
  39. if (son[u] == -) return;
  40. dfs2(son[u], rt, son_cost[u]);
  41. for (int i = head[u]; ~i; i = edge[i].next) {
  42. int v = edge[i].to;
  43. if (v != fa[u] && v != son[u]) dfs2(v, v, edge[i].cost);
  44. }
  45. }
  46.  
  47. //
  48. int mx[N<<], fg[N<<], mi[N<<];
  49. #define lson o<<1
  50. #define rson o<<1|1
  51.  
  52. void pushdown(int o) {
  53. if (fg[o]) {
  54. fg[lson] ^= ;
  55. fg[rson] ^= ;
  56. int tmp = mx[lson];
  57. mx[lson] = -mi[lson];
  58. mi[lson] = -tmp;
  59. tmp = mx[rson];
  60. mx[rson] = -mi[rson];
  61. mi[rson] = -tmp;
  62. fg[o] = ;
  63. }
  64. }
  65.  
  66. void pushup(int o) {
  67. mx[o] = max(mx[lson], mx[rson]);
  68. mi[o] = min(mi[lson], mi[rson]);
  69. }
  70.  
  71. void build(int o, int l, int r) {
  72. fg[o] = ;
  73. if (l == r) {
  74. mx[o] = a[l];
  75. mi[o] = a[l];
  76. } else {
  77. int mid = (l+r) >> ;
  78. build(lson, l, mid);
  79. build(rson, mid+, r);
  80. pushup(o);
  81. }
  82. }
  83.  
  84. void CHANGE(int o, int l, int r, int v, int w) {
  85. if (l == r) {
  86. mi[o] = mx[o] = w;
  87. } else {
  88. pushdown(o);
  89. int mid = (l + r) >> ;
  90. if (mid >= v) CHANGE(lson, l, mid, v, w);
  91. else CHANGE(rson, mid+, r, v, w);
  92. pushup(o);
  93. }
  94. }
  95.  
  96. void nega(int o, int l, int r, int L, int R) {
  97. if (l >= L && r <= R) {
  98. fg[o] ^= ;
  99. int tmp = mx[o];
  100. mx[o] = -mi[o];
  101. mi[o] = -tmp;
  102. return;
  103. }
  104. pushdown(o);
  105. int mid = (l+r) >> ;
  106. if (mid >= L) nega(lson, l, mid, L, R);
  107. if (mid < R) nega(rson, mid+, r, L, R);
  108. pushup(o);
  109. }
  110.  
  111. void NEGATE(int x, int y, int n) {
  112. while (top[x] != top[y]) {
  113. if (dep[top[x]] < dep[top[y]]) swap(x, y);
  114. nega(, , n, dfn[top[x]], dfn[x]);
  115. x = fa[top[x]];
  116. }
  117. if (x == y) return ;
  118. if (dep[x] > dep[y]) swap(x, y);
  119. nega(, , n, dfn[son[x]], dfn[y]);
  120. }
  121.  
  122. int query(int o, int l ,int r, int L, int R) {
  123. if (l >= L && r <= R) {
  124. return mx[o];
  125. }
  126. pushdown(o);
  127. int mid = (l+r) >> ;
  128. int ans = -(<<);
  129. if (L <= mid) ans = max(ans, query(lson, l, mid, L, R));
  130. if (R > mid) ans = max(ans, query(rson, mid+, r, L, R));
  131. pushup(o);
  132. return ans;
  133. }
  134.  
  135. int QUERY(int x, int y, int n) {
  136. if (x == y) return ;
  137. int ans = -(<<);
  138. while (top[x] != top[y]) {
  139. if (dep[top[x]] < dep[top[y]]) swap(x, y);
  140. ans = max(ans, query(, , n, dfn[top[x]], dfn[x]));
  141. x = fa[top[x]];
  142. }
  143. if (x == y) return ans;
  144. if (dep[x] > dep[y]) swap(x, y);
  145. ans = max(ans, query(, , n, dfn[son[x]], dfn[y])); // 注意这里是son[x]
  146. return ans;
  147. }
  148.  
  149. void init() {
  150. idx = cntE = ;
  151. memset(head, -, sizeof head);
  152. memset(son, -, sizeof son);
  153. }
  154.  
  155. // 区间更新 点更新 区间查询
  156. int main() {
  157. int n, T;
  158. scanf("%d",&T);
  159. int cas = ;
  160. while (T--) {
  161. scanf("%d", &n); init();
  162. int u, v, w;
  163. for (int i = ; i < n; ++i) scanf("%d%d%d", &u, &v, &w), addedge(u, v, w, i);
  164. dfs1(, , ); dfs2(, , ); build(, , n);
  165. char op[];
  166. while (~scanf("%s", op)) {
  167. if (*op == 'D') break;
  168. scanf("%d%d", &u, &v);
  169. if (*op == 'Q') printf("%d\n", QUERY(u, v, n));
  170. else if (*op == 'C') CHANGE(, , n, dfn[road[u]], v);
  171. else NEGATE(u, v, n);
  172. }
  173. }
  174. return ;
  175. }

一组数据

/**
2

7
1 2 1
2 3 7
3 4 8
4 5 6
5 6 9
6 7 1
N 4 7
C 2 3
N 1 7
C 2 7
N 1 5
C 4 7
D

6
1 2 8
2 3 8
3 4 7
4 5 2
5 6 10
N 6 1
C 1 2
N 3 6
N 4 1
N 1 6
Q 2 6
D

Output:
8
1
7
8

10
-10
7
*/

POJ3237-Tree (树链剖分,线段树区间更新+点更新+区间查询)的更多相关文章

  1. POJ3237 Tree 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...

  2. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  3. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  4. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  5. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  6. 【CF725G】Messages on a Tree 树链剖分+线段树

    [CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...

  7. 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并

    题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...

  8. Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  9. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  10. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

随机推荐

  1. JS代码片段:appendHTML 和 insertAdjacentHTML

    function appendHTML(container,html,position){ position =position || 'after'; var objE = document.cre ...

  2. 在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序(老罗学习笔记3)

    简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中.接着,在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)一文中举例子说明了如何在 ...

  3. C#获取一个文件的扩展名

    C#获取一个文件的扩展名System.IO.Path.GetExtension( "文件名 ");ChangeExtension   更改路径字符串的扩展名. Combine   ...

  4. BZOJ 1297 迷路(矩阵)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1297 题意:给出一个带权有向图,权值为1-9,顶点个数最多为10.从1出发恰好在T时刻到 ...

  5. Android移动应用开发中常见的经验技巧总结

    转:http://wwwdevstorecn/essay/essayInfo/6128.html 1. 对话保持的解决方案. 要求: 1.app中使用webview访问具体网站的内容,但是app与服务 ...

  6. Android开发之消息机制

    转:http://stackvoid.com/introduction-to-Message-Handler-in-Android/ http://blog.dreamtobe.cn/2016/03/ ...

  7. C# WebBrowser准确判断网页最终装载完毕

    == 最近写了个软件叫WebAutoScript,目的用于,网页的自动操作处理,就是说,所有你在网页上面的操作,都可以录到一个脚本中,然后可以回放这个操作过程..我是说任何过程. 程序是用C#写的,其 ...

  8. 如何使用UIAutomation进行iOS 自动化测试(Part I)

    转自:http://www.cnblogs.com/vowei/archive/2012/08/10/2631949.html 写在前面 研究iOS的自动化测试也有些日子了,刚开始的时候,一直苦于找不 ...

  9. 设置图片Alpha

    Drawable ico = getResources().getDrawable(R.drawable.search_box);                       mSearchLayou ...

  10. Eclipse中设置在创建新类时自动生成注释

    方法一:Eclipse中设置在创建新类时自动生成注释 windows-->preference Java-->Code Style-->Code Templates code--&g ...