id=2763" target="_blank" style="">题目链接:poj 2763 Housewife Wind

题目大意:给定一棵树,然后2种操作:

  • 0 u:输出路径s到u的权值和,而且s变成u
  • 1 i w:节点i添加w

解题思路:树链剖分,然后用线段树维护,单点改动区间查询。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int maxn = 100005;
  6. int N, Q, S, ne;
  7. int first[maxn], jump[maxn * 2];
  8. int id, far[maxn], son[maxn], cnt[maxn], dep[maxn], top[maxn], idx[maxn];
  9. struct Edge {
  10. int u, v, w;
  11. void set (int u, int v, int w) {
  12. this->u = u;
  13. this->v = v;
  14. this->w = w;
  15. }
  16. }ed[maxn * 2];
  17. void dfs_fir (int u, int pre, int d) {
  18. far[u] = pre;
  19. dep[u] = d;
  20. cnt[u] = 1;
  21. son[u] = 0;
  22. for (int i = first[u]; i + 1; i = jump[i]) {
  23. int v = ed[i].v;
  24. if (v == pre)
  25. continue;
  26. dfs_fir(v, u, d+1);
  27. cnt[u] += cnt[v];
  28. if (cnt[son[u]] < cnt[v])
  29. son[u] = v;
  30. }
  31. }
  32. void dfs_sec(int u, int rot) {
  33. top[u] = rot;
  34. idx[u] = id++;
  35. if (son[u])
  36. dfs_sec(son[u], rot);
  37. for (int i = first[u]; i + 1; i = jump[i]) {
  38. int v = ed[i].v;
  39. if (v == far[u] || v == son[u])
  40. continue;
  41. dfs_sec(v, v);
  42. }
  43. }
  44. inline void add_Edge(int u, int v, int w) {
  45. ed[ne].set(u, v, w);
  46. jump[ne] = first[u];
  47. first[u] = ne++;
  48. }
  49. #define lson(x) ((x)<<1)
  50. #define rson(x) (((x)<<1)|1)
  51. typedef long long ll;
  52. int lc[maxn << 2], rc[maxn << 2];
  53. ll s[maxn << 2];
  54. inline void pushup(int u) {
  55. s[u] = s[lson(u)] + s[rson(u)];
  56. }
  57. void build (int u, int l, int r) {
  58. lc[u] = l;
  59. rc[u] = r;
  60. s[u] = 0;
  61. if (l == r)
  62. return;
  63. int mid = (l + r) / 2;
  64. build(lson(u), l, mid);
  65. build(rson(u), mid + 1, r);
  66. pushup(u);
  67. }
  68. void modify (int u, int x, int w) {
  69. if (lc[u] == x && rc[u] == x) {
  70. s[u] = w;
  71. return;
  72. }
  73. int mid = (lc[u] + rc[u]) / 2;
  74. if (x <= mid)
  75. modify(lson(u), x, w);
  76. else
  77. modify(rson(u), x, w);
  78. pushup(u);
  79. }
  80. ll query(int u, int l, int r) {
  81. if (l <= lc[u] && rc[u] <= r)
  82. return s[u];
  83. ll ret = 0;
  84. int mid = (lc[u] + rc[u]) / 2;
  85. if (l <= mid)
  86. ret += query(lson(u), l, r);
  87. if (r > mid)
  88. ret += query(rson(u), l, r);
  89. return ret;
  90. }
  91. void init () {
  92. ne = 0;
  93. id = 1;
  94. int u, v, w;
  95. memset(first, -1, sizeof(first));
  96. for (int i = 0; i < N - 1; i++) {
  97. scanf("%d%d%d", &u, &v, &w);
  98. add_Edge(u, v, w);
  99. add_Edge(v, u, w);
  100. }
  101. dfs_fir(1, 0, 0);
  102. dfs_sec(1, 1);
  103. build(1, 1, N);
  104. for (int i = 0; i < N - 1; i++) {
  105. if (dep[ed[i*2].u] < dep[ed[i*2].v])
  106. swap(ed[i*2].u, ed[i*2].v);
  107. modify(1, idx[ed[i*2].u], ed[i*2].w);
  108. }
  109. }
  110. ll solve (int u, int v) {
  111. ll ret = 0;
  112. int p = top[u], q = top[v];
  113. while (p != q) {
  114. if (dep[p] < dep[q]) {
  115. swap(p, q);
  116. swap(u, v);
  117. }
  118. ret += query(1, idx[p], idx[u]);
  119. u = far[p];
  120. p = top[u];
  121. }
  122. if (u == v)
  123. return ret;
  124. if (dep[u] > dep[v])
  125. swap(u, v);
  126. ret += query(1, idx[son[u]], idx[v]);
  127. return ret;
  128. }
  129. int main () {
  130. while (scanf("%d%d%d", &N, &Q, &S) == 3) {
  131. init();
  132. int k, u, w;
  133. while (Q--) {
  134. scanf("%d%d", &k, &u);
  135. if (k) {
  136. scanf("%d", &w);
  137. modify(1, idx[ed[u*2 - 2].u], w);
  138. } else {
  139. printf("%lld\n", solve(S, u));
  140. S = u;
  141. }
  142. }
  143. }
  144. return 0;
  145. }

版权声明:本文博客原创文章,博客,未经同意,不得转载。

poj 2763 Housewife Wind(树链拆分)的更多相关文章

  1. POJ 2763 Housewife Wind (树链剖分 有修改单边权)

    题目链接:http://poj.org/problem?id=2763 n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置:1操作是第i条 ...

  2. POJ 2763 Housewife Wind 树链拋分

    一.前言 这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了..于是,还是低级错误背锅啊....代码能力有待进一步提升2333333 二.题意 某家庭主 ...

  3. POJ - 2763 Housewife Wind (树链剖分/ LCA+RMQ+树状数组)

    题意:有一棵树,每条边给定初始权值.一个人从s点出发.支持两种操作:修改一条边的权值:求从当前位置到点u的最短路径. 分析:就是在边可以修改的情况下求树上最短路.如果不带修改的话,用RMQ预处理LCA ...

  4. poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询

    /** problem: http://poj.org/problem?id=2763 **/ #include<stdio.h> #include<stdlib.h> #in ...

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

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

  6. POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新

    题目来源:POJ 2763 Housewife Wind 题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x 思路:树上两点u, v距离为 ...

  7. POJ2763 Housewife Wind 树链剖分 边权

    POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...

  8. POJ 2763 Housewife Wind(树链剖分)(线段树单点修改)

    Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 10378   Accepted: 2886 D ...

  9. poj 2763 Housewife Wind (树链剖分)

    题目链接:http://poj.org/problem?id=2763 题意: 给定一棵含n个结点的树和树的边权,共有q次操作,分为两种 0 c :求从位置s到c的距离,然后s变成c 1 a b:把第 ...

随机推荐

  1. Swift - 警告提示框(UIAlertController)的用法

    import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoa ...

  2. shell脚本if条件总结

    原文链接:https://geniuspeng.github.io/2018/03/12/shell-if/ shell编程中,if-then是一种常见的控制流命令,而if的条件判断一般采用内置命令t ...

  3. 【2024】求X到Y之间的整数和

    Time Limit: 3 second Memory Limit: 2 MB [问题描述] 计算X到Y之间的整数和(要求用函数实现).注意输入时X不一定小于Y,且X.Y不一定都是整数. [输入] 两 ...

  4. js,jquery遍历数组,对象

    each的用法  1.数组中的each 复制代码 var arr = [ "one", "two", "three", "four ...

  5. 【2001】关于N!的问题

    Time Limit: 3 second Memory Limit: 2 MB 编写程序,计算n!以十进制数形式表示的数中最右边一个非零数字,并找出在它右边有几个零. 例如:12!=1*2*3*4*5 ...

  6. Android中的动画详解系列【2】——飞舞的蝴蝶

    这一篇来使用逐帧动画和补间动画来实现一个小例子,首先我们来看看Android中的补间动画. Android中使用Animation代表抽象的动画类,该类包括下面几个子类: AlphaAnimation ...

  7. 编辑器vim简介

    vi简介 vi是"Visual interface"的简称,它在Linux上的地位就仿佛Edit程序在DOS上一样.它可以执行输出.删除.查找.替换.块操作等众多文本操作,而且用户 ...

  8. Android 面试之横竖屏切换的Activity生命周期

    public class EngineerJspActivity extends Activity { private static String Tag = "EngineerJspAct ...

  9. Matlab Tricks(二十五)—— plot 属性

    marker: 边缘:'MarkerEdgeColor', [],(RGB 配色) 填充:'MarkerFaceColor', [](RGB 配色)

  10. noip刷题记录 20170818

    天天爱跑步 lca + 树上差分 #include<iostream> #include<cstdio> #include<cstdlib> #include< ...