洛谷——P3833 [SHOI2012]魔法树
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行,每行是以下两种中的一种:
A u v d,表示将u到v的路径上的所有节点的果子数加上d;0 ≤ u,v <N,0 < d < 100000
Q u,表示询问以u为根的子树中的总果子数,注意是包括u本身的。
输出格式:
对于所有的Query操作,依次输出询问的答案,每行一个。答案可能会超过2^32 ,但不会超过10^15 。
输入输出样例
树链剖分模板题,注意一下细节即可
#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]魔法树的更多相关文章
- 洛谷 P3833 [SHOI2012]魔法树
题目背景 SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点 ...
- [洛谷P3833][SHOI2012]魔法树
题目大意:给一棵树,路径加,子树求和 题解:树剖 卡点:无 C++ Code: #include <cstdio> #include <iostream> #define ma ...
- 洛谷3833 [SHOI2012]魔法树
SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点0是根节点 ...
- P3833 [SHOI2012]魔法树
思路 树剖板子 注意给出点的编号是从零开始的 代码 #include <cstdio> #include <algorithm> #include <cstring> ...
- 洛谷P3833 [SHOI2012]魔法树(树链剖分)
传送门 树剖板子…… 一个路径加和,线段树上打标记.一个子树询问,dfs的时候记录一下子树的区间就行 // luogu-judger-enable-o2 //minamoto #include< ...
- [SHOI2012]魔法树
题目:洛谷P3833. 题目大意:给你一棵树,有两种操作:1.给两个点和它们之间的最短路上的所有点加上一个值:2.询问以某个点为根的子树的子树和.你需要实现这个功能. 解题思路:如果只有最后才询问的话 ...
- 树链剖分【洛谷P3833】 [SHOI2012]魔法树
P3833 [SHOI2012]魔法树 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节 ...
- 树链剖分【P3833】 [SHOI2012]魔法树
Description Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点0是根节点,每个节点u的 ...
- 题解 P3833 【[SHOI2012]魔法树】
题目 直通车 很显然这是个树刨的板子,树上链查询和子树查询 注意: 1.这个点的树根为 0 而不是 1 所以注意读图时点标号 +1 就解决了 2.注意数据范围\(2^{32}\) 然后板子就能过了 n ...
随机推荐
- Mysql经常使用函数
-----------------------------字符串函数--------------------------------------- ----拼接字符串.不论什么字符串与null拼接为n ...
- Java 实现的断点下载
该断点下载可应用于浏览器或者迅雷等下载工具的下载,实现方式有多种多样的,本文仅仅研究了单线程的下载.迅雷等下载工具会自己主动将下载资源分块并记录每块的起始位置,然后依据系统性能.起多线程下载. 1. ...
- bzoj 1453 双面棋盘
题目大意: 一个黑白方格图 支持单点修改 查询黑色与白色联通快个数 思路: 可以把每一行压为一个点 使用线段树来维护 然后两行合并的时候使用并查集来合并 #include<iostream> ...
- JSP-Runoob:JSP 表单处理
ylbtech-JSP-Runoob:JSP 表单处理 1.返回顶部 1. JSP 表单处理 我们在浏览网页的时候,经常需要向服务器提交信息,并让后台程序处理.浏览器中使用 GET 和 POST 方法 ...
- MySQL 1071错误解决办法
今天在使用mysql时,又遇到了如博文标题所示的问题,以前针对该问题未进行记录,今天特意进行说明存档. 该问题是由键值字段长度过长导致.mysql支持数据库表单一键值的最大长度不能超过 ...
- shell脚本-高级变量
shell脚本-高级变量 字符串变量切片 ${#var}: 返回字符串变量var的长度 ${var:offset}: 返回字符串变量var中从第offset个字符后(不包括第offset 个字符)的字 ...
- Python机器学习算法 — KNN分类
KNN简介 K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一.KNN分类算法属于监督学习. 最简单最初级的分类器是将全部的训练 ...
- Elasticsearch创建文档,利用Kibana进行创建文档
首先先来了解一下什么是文档,es里边的文档相当于mysql数据库里边的一张表,如果你用过mongodb的话,那么肯定对es这种数据格式一定很了解了.接下来我们来看一下如何创建一个文档. PUT /sd ...
- Coursera公开课-Machine_learing:编程作业8(2016-10-06 20:49)
Anomaly Detection and Recommender Systems 本周编程作业分为两部分:异常检测和推荐系统. 异常检测:本质就是使用样本的到特种值的gaussian分布,来预估正确 ...
- nodejs全局安装路径的位置
一般nodejs安装在默认的C盘,如果不知道安装在哪里,可以打开控制面板-系统和安全-系统-高级配置中找到 所谓全局安装: 是指安装在node中node_module的根目录里,可以在电脑的任何位置调 ...