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

  想了想似乎只能树链剖分了。。好久没写链剖+数据结构了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. 实现一个 myshell

    重点 1.动手前首先要想清楚为什么实现一个 shell 要用到 fork (创建子进程),为什么不能把活全由 shell 干了呢?原因其实很简单,进程是运行的程序,一个进程就只能有一个程序(这个知识点 ...

  2. Fiori缓存与它的清除

    最近在修改已有的Fiori应用,遇到了缓存上的一点问题,导致对Fiori应用的代码修改不能在前端页面生效.现将自己查到的一篇好资料翻译过来,以供参考.以下为正文. 2017.12.19更新:最近又遇到 ...

  3. 小白的Python之路 day4 生成器并行运算

    一.概述 我们已经明白生成器内部的结构,其实就是通过像函数这样的东西实现的! 多线程和单线程:简单来说多线程就是并行运算,单线程就是串行运算 二.生成器执行原理 第一步:生成一个生成器  第二步:执行 ...

  4. ElasticSearch 学习记录之ES如何操作Lucene段

    近实时搜索 提交(Commiting)一个新的段到磁盘需要一个 fsync 来确保段被物理性地写入磁盘,这样在断电的时候就不会丢失数据.但是每次提交的一个新的段都fsync 这样操作代价过大.可以使用 ...

  5. Collection源码图

    java基础是否扎实,在于多读源码,比如集合 IO Socket 多线程并发包等 最近将集合框架的源码读了以下,总结了一些,下图所示

  6. 最近提交一个mysql5.7的bug,提醒自己以后注意写SQL要规范

    最近帮朋友提交一个mysql5.7的bug , oracle mysql 的大神还回复我 , 以后注意书写sql规范 , 潜台词是不是不要给他们增加工作量 https://bugs.mysql.com ...

  7. springBoot系列教程08:拦截器(Interceptor)的使用

    拦截器intercprot  和 过滤器 Filter 其实作用类似 在最开始接触java 使用struts2的时候,里面都是filter 后来springmvc时就用interceptor 没太在意 ...

  8. Asp.net IIS Express 无法启动 解决办法

    http://www.mamicode.com/info-detail-1893424.html 一 .其他项目都可以,就这么一个不行 用记事本或者其他什么文本编辑器,打开项目的.csproj文件,定 ...

  9. leetcode — linked-list-cycle-ii

    /** * Source : https://oj.leetcode.com/problems/linked-list-cycle-ii/ * * Given a linked list, retur ...

  10. LeetCode题目总结(三)

    我的代码在github上,https://github.com/WINTERFELLS/LeetCode-Answers 这里只提供个人的解题思路,不一定是最好的. 41-60: 给定一个排好序的数组 ...