[bzoj2836] 魔法树
俩操作:增加路径上的点的权值。查询子树的权值和。
想了想似乎只能树链剖分了。。好久没写链剖+数据结构了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] 魔法树的更多相关文章
- 【树链剖分】【dfs序】【线段树】bzoj2836 魔法树
这道题告诉我们:树链剖分的重标号就是dfs序. #include<cstdio> #include<algorithm> using namespace std; #defin ...
- noip模拟赛(一)魔法树
魔法树 (mahou.pas/c/cpp) [问题描述] 魔法使moreD在研究一棵魔法树. 魔法树顾名思义,这货是一棵树,奇葩的是魔法树上的每一条边都拥有一个魔法属性,如果不那么奇葩就不是moreD ...
- P3833 [SHOI2012]魔法树
思路 树剖板子 注意给出点的编号是从零开始的 代码 #include <cstdio> #include <algorithm> #include <cstring> ...
- [洛谷P3833][SHOI2012]魔法树
题目大意:给一棵树,路径加,子树求和 题解:树剖 卡点:无 C++ Code: #include <cstdio> #include <iostream> #define ma ...
- 树链剖分【洛谷P3833】 [SHOI2012]魔法树
P3833 [SHOI2012]魔法树 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节 ...
- 树链剖分【P3833】 [SHOI2012]魔法树
Description Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点0是根节点,每个节点u的 ...
- [SHOI 2012] 魔法树
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2836 [算法] 树链剖分 时间复杂度 : O(NlogN ^ 2) [代码] #in ...
- 洛谷 3833 SHOI 2012 魔法树
[题解] 树链剖分模板题.. #include<cstdio> #include<algorithm> #include<queue> #define N 5000 ...
- 洛谷——P3833 [SHOI2012]魔法树
P3833 [SHOI2012]魔法树 题目背景 SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的 ...
随机推荐
- C#中MessageBox用法大全(附效果图)
1.最简单的,只显示提示信息 2. 可以给消息框加上标题. 3. "确定"和"取消" 4. 给MessageBox加上一个Icon,.net提供常见的Icon共 ...
- Missing number in array
Given an array of size n-1 and given that there are numbers from 1 to n with one missing, the missin ...
- 大赛获奖选手专访 | 冷燕冰:最佳设计奖TIMING里的时机和时序
Mockplus三周年原型设计大赛,从筹备到11月21日完美落幕,50余天的时光,已成为过去.这场近千人参赛的原型设计大赛,我想,无论是于主办方,于参赛选手,于专家评委,还是于每一个关注和参与的人,都 ...
- 树链剖分X2
1.ZJOI树的统计 板子题 因为初始化没打改了几个小时 改到双腿软着出的机房(身体素质感人 #include<iostream> #include<cstdio> #incl ...
- MyBatis map foreach
以下资料来源于网络,仅供参考学习. mybatis 遍历map实例 map 数据如下 Map<String,List<Long>>. 测试代码如下: public vo ...
- 与apk签名有关的那些概念与命令
一.概念篇 1.消息摘要-Message Digest 消息摘要:在消息数据上,执行一个单向的hash函数,生成一个固定长度的hash值,这个Hash值就是消息摘要,也成为数字指纹. 消息摘要特点: ...
- Regular expressions in lexing and parsing(翻译)
词法分析和语法分析中的正则表达式 (英文原文来自rob pike 的博客 https://commandcenter.blogspot.jp/2011/08/regular-expressions-i ...
- 房上的猫:while循环与do-while循环,debug的调试运用
一.循环结构 1.循环不是无休止进行的,满足一定条件的时候循环才会继续,称为"循环条件",循环条件不满足的时候,循环退出 2.循环结构是反复进行相同的或类似的一系列操作,称为&qu ...
- 使用C#开发数据库应用系统 习题
错题积累 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
- Django学习日记01_环境搭建
1. 使用Vagrant 创建ubuntu虚拟机: 首先安装vagrant,网上有比较多的方法,如:http://www.th7.cn/system/mac/201405/55421.shtml 我使 ...