题目

直通车

很显然这是个树刨的板子,树上链查询和子树查询

注意:

1.这个点的树根为 0 而不是 1 所以注意读图时点标号 +1 就解决了

2.注意数据范围\(2^{32}\)

然后板子就能过了

node

  1. #include <iostream>
  2. #include <cstdio>
  3. #define N 100005
  4. #define int long long
  5. #define lson rt << 1
  6. #define rson rt << 1|1
  7. using namespace std;
  8. int n,m,r;
  9. int pre[N],dep[N],fa[N],son[N],siz[N],top[N],dfn[N],dfn2[N],cnt;
  10. namespace Seg{
  11. struct Tree{
  12. int sum,len,lazy;
  13. }tree[N << 1];
  14. void push_up(int rt){
  15. tree[rt].sum = tree[lson].sum + tree[rson].sum;
  16. }
  17. void build(int rt,int l,int r){
  18. tree[rt].len = r - l + 1;
  19. if(l == r){
  20. tree[rt].sum = 0;
  21. return;
  22. }
  23. int mid = (l + r)>>1;
  24. build(lson, l, mid);
  25. build(rson, mid + 1, r);
  26. push_up(rt);
  27. }
  28. void pushdown(int rt) {
  29. if (tree[rt].lazy){
  30. tree[lson].sum += tree[rt].lazy * tree[lson].len;
  31. tree[rson].sum += tree[rt].lazy * tree[rson].len;
  32. tree[lson].lazy += tree[rt].lazy;
  33. tree[rson].lazy += tree[rt].lazy;
  34. tree[rt].lazy = 0;
  35. }
  36. }
  37. void update(int rt,int k,int l,int r,int L,int R){
  38. if(l >= L && r <= R){
  39. tree[rt].sum += k * tree[rt].len;
  40. tree[rt].lazy += k;
  41. return;
  42. }
  43. pushdown(rt);
  44. int mid = (l + r) >> 1;
  45. if(mid >= L) update(lson, k, l, mid, L, R);
  46. if(mid < R) update(rson, k, mid + 1, r, L, R);
  47. push_up(rt);
  48. }
  49. int query(int rt,int l,int r,int L,int R){
  50. if(l >= L&& r <= R) return tree[rt].sum;
  51. pushdown(rt);
  52. int mid = (l + r)>>1,ans = 0;
  53. if(L <= mid) ans += query(lson,l,mid,L,R);
  54. if(mid < R) ans += query(rson,mid + 1,r,L,R);
  55. return ans;
  56. }
  57. }
  58. namespace Cut {
  59. struct edge{
  60. int v,nxt;
  61. }e[N << 1];
  62. int head[N],js;
  63. void add_edge(int u,int v){
  64. e[++js].v = v;e[js].nxt = head[u];head[u] = js;
  65. }
  66. void dfs(int x,int f,int d){
  67. dep[x] = d,fa[x] = f,siz[x] = 1;
  68. for(int i = head[x]; i;i = e[i].nxt){
  69. int v = e[i].v;
  70. if(v != fa[x]){
  71. dfs(v, x, d + 1);
  72. siz[x] += siz[v];
  73. if(!son[x]||siz[son[x]] < siz[v])
  74. son[x] = v;
  75. }
  76. }
  77. }
  78. void dfs2(int x,int tp){
  79. dfn[x] =++cnt,pre[cnt] = x,top[x] = tp;
  80. if(son[x]) dfs2(son[x],tp);
  81. for(int i = head[x]; i; i = e[i].nxt){
  82. int v = e[i].v;
  83. if(v != fa[x]&&v != son[x]) dfs2(v,v);
  84. }
  85. }
  86. int query_tree(int x){
  87. return Seg::query(1, 1, n, dfn[x],dfn[x] + siz[x] - 1);
  88. }
  89. void change_sum(int x,int y,int k){
  90. while(top[x] != top[y]){
  91. if(dep[top[x]] < dep[top[y]]) swap(x,y);
  92. Seg::update(1, k, 1, n,dfn[top[x]], dfn[x]);
  93. x = fa[top[x]];
  94. }
  95. if(dep[x] > dep[y]) swap(x,y);
  96. Seg::update(1, k, 1, n,dfn[x], dfn[y]);
  97. }
  98. }
  99. signed main() {
  100. int Q;
  101. cin>>n;
  102. for (int i = 1, x, y; i < n; i++) {
  103. cin>>x>>y;
  104. Cut::add_edge(x + 1, y + 1);
  105. Cut::add_edge(y + 1, x + 1);
  106. }
  107. Cut::dfs(1, 0, 1);
  108. Cut::dfs2(1, 1);
  109. Seg::build(1, 1, n);
  110. cin >> Q;
  111. while(Q--){
  112. int x,y,z;
  113. char opt;
  114. cin >> opt;
  115. if (opt == 'A') cin>>x>>y>>z,Cut::change_sum(x + 1, y + 1, z);
  116. if (opt == 'Q') cin>>x,printf("%lld\n", Cut::query_tree(x + 1));
  117. }
  118. }

题解 P3833 【[SHOI2012]魔法树】的更多相关文章

  1. 洛谷——P3833 [SHOI2012]魔法树

    P3833 [SHOI2012]魔法树 题目背景 SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的 ...

  2. 洛谷 P3833 [SHOI2012]魔法树

    题目背景 SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点 ...

  3. [洛谷P3833][SHOI2012]魔法树

    题目大意:给一棵树,路径加,子树求和 题解:树剖 卡点:无 C++ Code: #include <cstdio> #include <iostream> #define ma ...

  4. P3833 [SHOI2012]魔法树

    思路 树剖板子 注意给出点的编号是从零开始的 代码 #include <cstdio> #include <algorithm> #include <cstring> ...

  5. 树链剖分【洛谷P3833】 [SHOI2012]魔法树

    P3833 [SHOI2012]魔法树 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节 ...

  6. 树链剖分【P3833】 [SHOI2012]魔法树

    Description Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点0是根节点,每个节点u的 ...

  7. [SHOI2012]魔法树

    题目:洛谷P3833. 题目大意:给你一棵树,有两种操作:1.给两个点和它们之间的最短路上的所有点加上一个值:2.询问以某个点为根的子树的子树和.你需要实现这个功能. 解题思路:如果只有最后才询问的话 ...

  8. 洛谷3833 [SHOI2012]魔法树

    SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点0是根节点 ...

  9. noip模拟赛(一)魔法树

    魔法树 (mahou.pas/c/cpp) [问题描述] 魔法使moreD在研究一棵魔法树. 魔法树顾名思义,这货是一棵树,奇葩的是魔法树上的每一条边都拥有一个魔法属性,如果不那么奇葩就不是moreD ...

随机推荐

  1. 【C++】C++之类型转换

    作者:李春港 出处:https://www.cnblogs.com/lcgbk/p/14209848.html 目录 一.前言 二.static_cast 2.1 使用场景 2.2 实例 三.dyna ...

  2. springboot(一)入门篇

    作者:纯洁的微笑 出处:www.ityouknow.com 版权所有,欢迎保留原文链接进行转载:) 根据原文以下内容略有调整(由于SpringBoot版本更新引起) 什么是spring boot Sp ...

  3. 自动化运维工具-Ansible之5-流程控制

    自动化运维工具-Ansible之5-流程控制 目录 自动化运维工具-Ansible之5-流程控制 playbook条件语句 单条件 多条件 多条件运算 示例 playbook循环语句 with_ite ...

  4. git基础-git别名

    Git 并不会在你输入部分命令时自动推断出你想要的命令. 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名. 这里有一些例子你可以试试: $ ...

  5. scala模式匹配 case a @ b语法

    class caseTest { def main(args: Array[String]): Unit = { val c = Person(Student(1),"a") c ...

  6. Hbase-cdh5.14.2与kylin集成异常

    1.原先使用版本:apache-kylin-2.5.1-bin-hbase1x 原生版本 启动报错出现异常: Failed to find metadata store by url: kylin_m ...

  7. 【递归】P5461赦免战俘

    题目相关 原题链接:P5461 赦免战俘 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目背景 借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了! 题目描述 现有 \(2 ...

  8. Linux下最常用的10个文件压缩工具

    作者简介 李先生(Lemon),高级运维工程师(自称),SRE专家(目标),梦想在35岁买一辆保时捷.喜欢钻研底层技术,认为底层基础才是王道.一切新技术都离不开操作系统(CPU.内存.磁盘).网络等. ...

  9. 【剑指 Offer】12.矩阵中的路径

    题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格. 如果一条路径经过了矩阵的某一格,那么 ...

  10. 在CentOS上安装Singularity高性能容器

    什么是singularity容器 Singularity是劳伦斯伯克利国家实验室专门为大规模.跨节点HPC和DL工作负载而开发的容器化技术.具备轻量级.快速部署.方便迁移等诸多优势,且支持从Docke ...