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. Analyze提示:Value stored to &quot;***&quot;is never read

    text这个变量没有被使用,在当前类中搜索'text'这个变量发现仅仅是被赋值并没有被使用. 提示意思是:删除或者凝视这行代码;

  2. 分布式软件体系结构风格(C/S,B/S)

    分布式软件体系结构风格 1.  三层C/S结构 2.  三层B/S结构 了解很多其它软件体系结构 三层C/S结构(3-Tier C/S Architecture) §第1层:用户界面GUI-表示层-- ...

  3. Asp.NET之对象学习

    一.总述 二.具体介绍 1.Request对象 Request对象是用来获取client在请求一个页面或传送一个Form时提供的全部信息,这包含可以标识浏览器和用户的HTTP变量,存储在client的 ...

  4. 【HDU 1007】 Quoit Design

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1007 [算法] 答案为平面最近点对距离除以2 [代码] #include <algorith ...

  5. 洛谷 P1498 南蛮图腾 —— 模拟

    题目:https://www.luogu.org/problemnew/show/P1498 大约一年前该做的题...现在来填一下坑: 然而不怎么会模拟!还滚去看TJ了: 就是翻倍复制: \ 这个符号 ...

  6. openStack调试

  7. Mariadb-lib

    mariadb-libs-5.5.44-2.el7.centos.x86_64

  8. Vue.prototype的用法

    基础事例: 在vue项目main.js文件中: Vue.prototype.$appName = 'My App' 这样你可以通过在原型上定义它们使其在每个 Vue 的实例中可用. new Vue({ ...

  9. codevs2503失恋28天......(背包dp)

    503 失恋28天-缝补礼物  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold   题目描述 Description 话说上回他给女孩送了n件礼物,由于是廉价的所以 ...

  10. [Swift通天遁地]六、智能布局-(1)给视图添加尺寸和中心点的约束

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