题目大意:给一棵树,路径加,子树求和

题解:树剖

卡点:

C++ Code:

#include <cstdio>
#include <iostream>
#define maxn 100010 int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxn << 1];
inline void add(int a, int b) {
e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
} int n, m; namespace SgT {
long long V[maxn << 2], tg[maxn << 2];
int L, R, num; inline void pushdown(int rt, int len) {
long long &__tg = tg[rt];
V[rt << 1] += __tg * (len + 1 >> 1);
V[rt << 1 | 1] += __tg * (len >> 1);
tg[rt << 1] += __tg;
tg[rt << 1 | 1] += __tg;
__tg = 0;
}
void __add(int rt, int l, int r) {
if (L <= l && R >= r) {
V[rt] += static_cast<long long> (r - l + 1) * num;
tg[rt] += num;
return ;
}
int mid = l + r >> 1;
if (tg[rt]) pushdown(rt, r - l + 1);
if (L <= mid) __add(rt << 1, l, mid);
if (R > mid) __add(rt << 1 | 1, mid + 1, r);
V[rt] = V[rt << 1] + V[rt << 1 | 1];
}
void add(int __L, int __R, int __num) {
L = __L, R = __R, num = __num;
__add(1, 1, n);
} long long __ask(int rt, int l, int r) {
if (L <= l && R >= r) return V[rt];
int mid = l + r >> 1;
long long ans = 0;
if (tg[rt]) pushdown(rt, r - l + 1);
if (L <= mid) ans = __ask(rt << 1, l, mid);
if (R > mid) ans += __ask(rt << 1 | 1, mid + 1, r);
return ans;
}
long long ask(int __L, int __R) {
L = __L, R = __R;
return __ask(1, 1, n);
}
}
using SgT::add;
using SgT::ask; int fa[maxn], dep[maxn], sz[maxn];
int dfn[maxn], idx, top[maxn], son[maxn];
void dfs1(int u) {
sz[u] = 1;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa[u]) {
fa[v] = u;
dep[v] = dep[u] + 1;
dfs1(v);
sz[u] += sz[v];
if (!son[u] || sz[v] > sz[son[u]]) son[u] = v;
}
}
}
void dfs2(int u) {
dfn[u] = ++idx;
int v = son[u];
if (v) top[v] = top[u], dfs2(v);
for (int i = head[u]; i; i = e[i].nxt) {
v = e[i].to;
if (v != fa[u] && v != son[u]) {
top[v] = v;
dfs2(v);
}
}
} void modify(int x, int y, int z) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
add(dfn[top[x]], dfn[x], z);
x = fa[top[x]];
}
if (dep[x] > dep[y]) std::swap(x, y);
add(dfn[x], dfn[y], z);
}
long long query(int x) {
return ask(dfn[x], dfn[x] + sz[x] - 1);
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n;
for (int i = 1, a, b; i < n; i++) {
std::cin >> a >> b; a++, b++;
add(a, b);
add(b, a);
}
dfs1(1);
top[1] = 1;
dfs2(1);
std::cin >> m;
while (m --> 0) {
char op;
int x, y, z;
std::cin >> op >> x; x++;
if (op == 'A') {
std::cin >> y >> z; y++;
modify(x, y, z);
} else std::cout << query(x) << '\n';
}
return 0;
}

  

[洛谷P3833][SHOI2012]魔法树的更多相关文章

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

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

  2. 洛谷 P3833 [SHOI2012]魔法树

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

  3. 洛谷3833 [SHOI2012]魔法树

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

  4. P3833 [SHOI2012]魔法树

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

  5. 洛谷P3833 [SHOI2012]魔法树(树链剖分)

    传送门 树剖板子…… 一个路径加和,线段树上打标记.一个子树询问,dfs的时候记录一下子树的区间就行 // luogu-judger-enable-o2 //minamoto #include< ...

  6. [SHOI2012]魔法树

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

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

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

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

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

  9. 题解 P3833 【[SHOI2012]魔法树】

    题目 直通车 很显然这是个树刨的板子,树上链查询和子树查询 注意: 1.这个点的树根为 0 而不是 1 所以注意读图时点标号 +1 就解决了 2.注意数据范围\(2^{32}\) 然后板子就能过了 n ...

随机推荐

  1. POM中常用依赖包

    <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven ...

  2. 屏蔽Drupal中的“Notice: Undefined index”警告

    原因:drupal默认使用E_ALL,即输出所有错误和警告.我们只需要修改错误显示级别即可. 方法: 1. 打开\sites\default\settings.php 追加一行 ini_set('er ...

  3. apache Subversion 直接支持LDAP域群组

    如果你的Subversion已经用apache的ldap支持用户认证功能,你是否常常在想,既然都用ldap支持认证,为什么不直接支持域群组, 反而在authz文件里面一个一个的手工定义,或者有人用脚本 ...

  4. PLSQL-包函数存储过程

    包: 包是PLSQL中多个单元的逻辑组合,他将过程组合在一个包内容,以供用户调用,使用后,不需要程序员频繁的修改程序,可以保持程序的逻辑完整性,对包中的过程重新定义或者编译,以便修改部分功能,从而更好 ...

  5. 用libevent实现的echo服务器及telnet客户端

    以下代码在vs 2010编译通过,使用的libevent版本是:libevent-2.0.22,win7环境测试通过. 服务器实现: 1 流程图: 2 代码: // my_telnet.cpp : D ...

  6. lintcode702 连接两个字符串中的不同字符

    连接两个字符串中的不同字符   给出两个字符串, 你需要修改第一个字符串,将所有与第二个字符串中相同的字符删除, 并且第二个字符串中不同的字符与第一个字符串的不同字符连接 思路:遍历两个字符串,找到互 ...

  7. JDK源码分析:Short.java

    Short是基本数据类型short的包装类. 1)声明部: public final class Short extends Number implements Comparable<Short ...

  8. Java中定时器相关实现的介绍与对比之:Timer和TimerTask

    Timer和TimerTask JDK自带,具体的定时任务由TimerTask指定,定时任务的执行调度由Timer设定.Timer和TimerTask均在包java.util里实现. 本文基于java ...

  9. 【Python 开发】第二篇 :Python安装

    一.python3.x安装 1)由于centos7原本就安装了Python2,而且这个Python2不能被删除,因为有很多系统命令,比如yum都要用到. 官网:https://www.python.o ...

  10. Centos6配置开启FTP Server

    vsftpd作为FTP服务器,在Linux系统中是非常常用的.下面我们介绍如何在centos系统上安装vsftp. 什么是vsftpd vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序 ...