P3833 [SHOI2012]魔法树

题目背景

SHOI2012 D2T3

题目描述

Harry Potter 新学了一种魔法:可以让改变树上的果子个数。满心欢喜的他找到了一个巨大的果树,来试验他的新法术。

这棵果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u],保证有fa[u] < u。初始时,这棵果树上的果子都被 Dumbledore 用魔法清除掉了,所以这个果树的每个节点上都没有果子(即0个果子)。

不幸的是,Harry 的法术学得不到位,只能对树上一段路径的节点上的果子个数统一增加一定的数量。也就是说,Harry 的魔法可以这样描述:

Add u v d

表示将点u和v之间的路径上的所有节点的果子个数都加上d。

接下来,为了方便检验 Harry 的魔法是否成功,你需要告诉他在释放魔法的过程中的一些有关果树的信息:

Query u

表示当前果树中,以点u为根的子树中,总共有多少个果子?

输入输出格式

输入格式:

第一行一个正整数N (1 ≤ N ≤ 100000),表示果树的节点总数,节点以0,1,…,N − 1标号,0一定代表根节点。

接下来N − 1行,每行两个整数a,b (0 ≤ a < b < N),表示a是b的父亲。

接下来是一个正整数Q(1 ≤ ? ≤ 100000),表示共有Q次操作。

后面跟着Q行,每行是以下两种中的一种:

  1. A u v d,表示将u到v的路径上的所有节点的果子数加上d;0 ≤ u,v <N,0 < d < 100000

  2. Q u,表示询问以u为根的子树中的总果子数,注意是包括u本身的。

输出格式:

对于所有的Query操作,依次输出询问的答案,每行一个。答案可能会超过2^32 ,但不会超过10^15 。

输入输出样例

输入样例#1: 复制

4
0 1
1 2
2 3
4
A 1 3 1
Q 0
Q 1
Q 2
输出样例#1: 复制

3
3
2

树链剖分模板题,注意一下细节即可

#include<bits/stdc++.h>

#define N 1010100
#define LL long long
using namespace std; struct node {
LL to,next;
} e[N];
struct tree {
LL l,r,w,f;
} tr[N]; LL n,m,head[N],tot,ans; //(u,v)树上修改
//询问子树大小 void add(LL u,LL v) {
e[++tot].to=v,e[tot].next=head[u],head[u]=tot;
} LL dep[N],siz[N],son[N],fa[N];
void dfs(LL u,LL f,LL deep) {
dep[u]=deep,siz[u]=,fa[u]=f;
LL maxson=-;
for(LL i=head[u]; i; i=e[i].next) {
LL v=e[i].to;
if(v==f) continue;
dfs(v,u,deep+);
siz[u]+=siz[v];
if(siz[v]>maxson) maxson=siz[v],son[u]=v;
}
} LL top[N],id[N],item;
void dfs2(LL u,LL topf) {
id[u]=++item,top[u]=topf;
if(!son[u]) return;
dfs2(son[u],topf);
for(LL i=head[u]; i; i=e[i].next) {
LL v=e[i].to;
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
} void build(LL k,LL l,LL r) {
tr[k].l=l,tr[k].r=r;
if(l==r) return;
LL mid=(l+r)/;
build(k*,l,mid);
build(k*+,mid+,r);
} void upda(LL k) {
tr[k].w=tr[k*].w+tr[k*+].w;
}
void down(LL k) {
LL f=tr[k].f;
tr[k].f=;
tr[k*].w=(tr[k*].w+f*(tr[k*].r-tr[k*].l+));
tr[k*+].w=(tr[k*+].w+f*(tr[k*+].r-tr[k*+].l+));
tr[k*].f+=f,tr[k*+].f+=f;
} void change_LLerval(LL k,LL l,LL r,LL p) {
LL ll=tr[k].l,rr=tr[k].r,mid=(ll+rr)/;
if(ll>=l&&rr<=r) {
tr[k].w=(tr[k].w+(rr-ll+)*p);
tr[k].f+=p;
return;
}
if(tr[k].f) down(k);
if(l<=mid) change_LLerval(k*,l,r,p);
if(r>mid) change_LLerval(k*+,l,r,p);
upda(k);
} void ask_LLerval(LL k,LL l,LL r) {
LL ll=tr[k].l,rr=tr[k].r,mid=(ll+rr)/;
if(ll>=l&&rr<=r) {
ans+=tr[k].w;
return;
}
if(tr[k].f) down(k);
if(l<=mid) ask_LLerval(k*,l,r);
if(r>mid) ask_LLerval(k*+,l,r);
upda(k);
} void change(LL a,LL b,LL p) {
while(top[a]!=top[b]) {
if(dep[top[a]]<dep[top[b]]) swap(a,b);
change_LLerval(,id[top[a]],id[a],p);
a=fa[top[a]];
}
if(dep[a]<dep[b]) swap(a,b);
change_LLerval(,id[b],id[a],p);
} LL sum(LL a) {
ans=;
ask_LLerval(,id[a],id[a]+siz[a]-);
return ans;
} int main() {
scanf("%lld",&n);
for(LL a,b,i=; i<n; i++) {
scanf("%lld%lld",&a,&b);
add(a+,b+);
}
dfs(,,);
dfs2(,);
build(,,n);
scanf("%lld",&m);
for(LL a,b,c,i=; i<=m; i++) {
char x;
cin>>x;
if(x=='A') {
scanf("%lld%lld%lld",&a,&b,&c);
change(a+,b+,c);
} else {
scanf("%lld",&a);
printf("%lld\n",sum(a+));
}
}
return ;
}

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

  1. 洛谷 P3833 [SHOI2012]魔法树

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

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

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

  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. 【java项目实践】具体解释Ajax工作原理以及实现异步验证username是否存在+源代码下载(java版)

    一年前,从不知道Ajax是什么,伴随着不断的积累,到如今常常使用,逐渐有了深入的认识. 今天,假设想开发一个更加人性化,友好,无刷新,交互性更强的网页,那您的目标一定是Ajax. 介绍 在具体讨论Aj ...

  2. 云上kafka和自建kafka对比

    说起Kafka,许多使用者对它是又爱又恨.Kafka是一种分布式的.基于发布/订阅的消息系统,其极致体验让人欲罢不能,但操心的运维.复杂的安全策略.可靠性易用性的缺失.算不上极致的性能发挥.并不丰富的 ...

  3. MySQL create table as与create table like对照

          在MySQL数据库中,关于表的克隆有多种方式,比方我们能够使用create table ..as .. .也能够使用create table .. like ..方式. 然而这2种不同的方 ...

  4. 深入struts2(二) ---stuts2长处和主要包、类功能

    1.1     Struts2 上节已讲.struts2在webwork基础发展起来的mvc框架.MVC框架相信一般码农都比較了解,这里不再重说. 在这里只对于一下struts1,struts2做了哪 ...

  5. jQuery--编辑表格

    表格操作是我们常常遇到的,还记得刚開始学习牛腩新闻公布系统时.跟着视频进行表格的一些基本操作.而对它的原理与概念全然不懂,不过跟着老师的操作而进行操作. 通过这次学习,对表格的操作有了进一步的了解与掌 ...

  6. CoffeeScript里的字符串插值

    拼接字符串是我们常干的事情.与其用很多的 "" + "",不如用一下字符串插值,可读性好些. 方法是在字符串中加入#{ 变量.表达式.函数等} getOther ...

  7. 手动安装jar包到Maven本地仓库

    接手别人的一个项目,Maven工程,导入后,某些jar包找不到,然后从同事那复制Maven本地仓库的文件夹到我的电脑,发现依旧找不到.问题大致总结为:本地maven仓库存在jar,但是依然报Missi ...

  8. struts表单验证xml配置文件

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC &quo ...

  9. cropbox

    今天给大家分享一款基于jQuery头像裁剪插件cropbox,这是一款简单实用的jQuery头像在线裁剪插件.该插件适用于适用浏览器:IE8.360.FireFox.Chrome.Safari.Ope ...

  10. [Swift通天遁地]五、高级扩展-(12)扩展故事板中的元件添加本地化功能

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...