俩操作:增加路径上的点的权值。查询子树的权值和。

  想了想似乎只能树链剖分了。。好久没写链剖+数据结构了TAT

  一开始没开LL炸了一发(明明有想到的。。我果然是傻逼= =

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=;
struct zs{
int too,pre;
}e[maxn<<];int tot,last[maxn];
int lc[maxn<<],rc[maxn<<],tt;
ll sm[maxn<<],tag[maxn<<];
int dfn[maxn],sz[maxn],fa[maxn],top[maxn],dep[maxn],tim;
int i,j,k,n,m,x,y,lca,v; int ra;char rx;
inline int read(){
rx=getchar(),ra=;
while(rx<''||rx>'')rx=getchar();
while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra;
} inline void dfs1(int x){
sz[x]=,dep[x]=dep[fa[x]]+;
for(int i=last[x];i;i=e[i].pre)
dfs1(e[i].too),sz[x]+=sz[e[i].too];
}
inline void dfs2(int x,int chain){
top[x]=chain,dfn[x]=++tim;int i,mx=;
for(i=last[x];i;i=e[i].pre)if(sz[e[i].too]>sz[mx])mx=e[i].too;
if(!mx)return;
dfs2(mx,chain);
for(i=last[x];i;i=e[i].pre)if(e[i].too!=mx)dfs2(e[i].too,e[i].too);
}
inline int getlca(int a,int b){
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]])swap(a,b);
a=fa[top[a]];
}
return dep[a]<dep[b]?a:b;
} inline void insert(int a,int b){e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;} inline void pushdown(int x,int a,int b,int mid,int lc,int rc){
tag[lc]+=tag[x],tag[rc]+=tag[x],sm[lc]+=tag[x]*(mid-a+),sm[rc]+=tag[x]*(b-mid);
tag[x]=;
}
#define upd(x) sm[x]=sm[lc[x]]+sm[rc[x]];
inline void add(int x,int a,int b,int l,int r,int v){
// printf("add:%d %d %d %d--%d %d\n",x,a,b,l,r,v);
if(l<=a&&r>=b){tag[x]+=v,sm[x]+=(ll)(b-a+)*v;/*,printf("! %d\n",sm[x]);*/return;}
int mid=(a+b)>>;
if(tag[x])pushdown(x,a,b,mid,lc[x],rc[x]);
if(l<=mid)add(lc[x],a,mid,l,r,v);
if(r>mid) add(rc[x],mid+,b,l,r,v);
upd(x);//printf(" %d--%d %d %d %d\n",a,b,sm[x],sm[lc[x]],sm[rc[x]]);
}
inline ll query(int x,int a,int b,int l,int r){
if(l<=a&&r>=b)return sm[x];
int mid=(a+b)>>;
if(tag[x])pushdown(x,a,b,mid,lc[x],rc[x]);
if(r<=mid)return query(lc[x],a,mid,l,r);else
if(l>mid)return query(rc[x],mid+,b,l,r);else
return query(lc[x],a,mid,l,r)+query(rc[x],mid+,b,l,r);
}
inline void build(int a,int b){
tt++;
if(a==b)return;
int mid=(a+b)>>,x=tt;
lc[x]=tt+,build(a,mid),rc[x]=tt+,build(mid+,b);
} inline void ADD(int x,int y,int v){
while(top[x]!=top[y]){
add(,,n,dfn[top[x]],dfn[x],v);
x=fa[top[x]];
}
add(,,n,dfn[y],dfn[x],v);
}
/*inline ll QUERY(int x,int y){
ll sum=0;
while(top[x]!=top[y]){
sum+=query(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
return sum+query(1,1,n,dfn[y],dfn[x]);
}*/ int main(){
n=read();
for(i=;i<n;i++)x=read()+,y=read()+,fa[y]=x,insert(x,y);
dfs1(),dfs2(,);
build(,n);char id;
for(m=read();m;m--){
for(id=getchar();id<'A'||id>'Z';id=getchar());
if(id=='A'){
x=read()+,y=read()+,v=read(),
lca=getlca(x,y);//printf(" %d %d lca:%d\n",x,y,lca);
ADD(x,lca,v),ADD(y,lca,v),add(,,n,dfn[lca],dfn[lca],-v);
}else{
x=read()+;
//ll sum=QUERY(x,lca)+QUERY(y,lca)-query(1,1,n,dfn[lca],dfn[lca]);
ll sum=query(,,n,dfn[x],dfn[x]+sz[x]-);
printf("%lld\n",sum);
}
}
return ;
}

[bzoj2836] 魔法树的更多相关文章

  1. 【树链剖分】【dfs序】【线段树】bzoj2836 魔法树

    这道题告诉我们:树链剖分的重标号就是dfs序. #include<cstdio> #include<algorithm> using namespace std; #defin ...

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

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

  3. P3833 [SHOI2012]魔法树

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

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

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

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

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

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

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

  7. [SHOI 2012] 魔法树

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2836 [算法] 树链剖分 时间复杂度 : O(NlogN ^ 2) [代码] #in ...

  8. 洛谷 3833 SHOI 2012 魔法树

    [题解] 树链剖分模板题.. #include<cstdio> #include<algorithm> #include<queue> #define N 5000 ...

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

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

随机推荐

  1. Java之数据类型,变量赋值

    Java中的基础数据类型(四类八种): 1.整数型 byte----使用byte关键字来定义byte型变量,可以一次定义多个变量并对其进行赋值,也可以不进行赋值.byte型是整型中所分配的内存空间是最 ...

  2. [array] leetcode - 34. Search for a Range - Medium

    leetcode - 34. Search for a Range - Medium descrition Given an array of integers sorted in ascending ...

  3. bzoj 4237: 稻草人

    Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要 ...

  4. 嵌入式设计初体验:永远的hello,world

    目前,xilinx的zynq系列FPGA炒的火热,SOC成为FPGA发展的必然趋势.可见所有功能均用硬件描述语言设计是不科学的.硬件逻辑独有的并行性使其在实时处理和并行算法中占尽优势,但当执行串行操作 ...

  5. Wamp环境搭建常见错误问题解决

    第一点.对于apache + php + mysql 的版本的正确选择 问题:网上有些教学视频已经很早了,然后很多人照着来,完全和视频里讲的一样,但是结果就是搭建不成功. 出现问题原因:三件套的版本选 ...

  6. javascript计算对象的长度

    计算对象的长度,即获取对象属性的个数 方法一:通过for in 遍历对象,并通过hasOwnProperty判断是否是对象自身可枚举的属性 var obj = {"c1":1,&q ...

  7. ES6(三)数组的扩展

    1.Array.form ES6中,Array.from = function(items,mapfn,thisArg) {  }   Array.from 用于将 类数组 和 可遍历对象(实现了It ...

  8. 《吸血鬼日记》(The Vampire Diaries)经典台词

    Best quotes from The Vampire Diary 1. I will start fresh, be someone new. 1.我要重新开始,做不一样的自己. 2. It’s ...

  9. 由浅入深理解Java线程池及线程池的如何使用

    前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...

  10. ping、traceroute原理

    说明:忘记从哪里拉的博文了,感谢! ping 用类型码为0的ICMP发请 求,受到请求的主机则用类型码为8的ICMP回应. ping程序来计算间隔时间,并计算有多少个包被送达.用户就可以判断网络大致的 ...