https://www.luogu.org/problem/show?pid=3178#sub

题目描述

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a 。操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

输入输出格式

输入格式:

第一行包含两个整数 N, M 。表示点数和操作数。接下来一行 N 个整数,表示树中节点的初始权值。接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。

输出格式:

对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

输入输出样例

输入样例#1:

5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
输出样例#1:

6
9
13

说明

对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不

会超过 10^6 。

树剖模板练习

 #include <algorithm>
#include <cstdio> #define LL long long using namespace std; const LL N(+);
const LL M(+);
LL n,m,u,v,w,op,val[N]; LL head[N],sumedge;
struct Edge
{
LL u,v,next;
Edge(LL u=,LL v=,LL next=):
u(u),v(v),next(next){}
}edge[M<<];
inline void ins(LL u,LL v)
{
edge[++sumedge]=Edge(u,v,head[u]);
head[u]=sumedge;
} LL size[N],deep[N],dad[N],son[N],top[N],dfn[N],id[N],cnt;
void DFS(LL x,LL father,LL deepth)
{
deep[x]=deepth;
dad[x]=father;
size[x]=;
for(LL i=head[x];i;i=edge[i].next)
{
LL v=edge[i].v;
if(dad[x]==v) continue;
DFS(v,x,deepth+);
size[x]+=size[v];
if(size[son[x]]<size[v]) son[x]=v;
}
}
void DFS_(LL x,LL Top)
{
top[x]=Top;
id[x]=++cnt,dfn[cnt]=x;
if(son[x]) DFS_(son[x],Top);
for(LL i=head[x];i;i=edge[i].next)
{
LL v=edge[i].v;
if(dad[x]!=v&&son[x]!=v) DFS_(v,v);
}
} struct Tree
{
LL l,r,mid,flag,val;
}tree[N<<];
inline void Tree_up(LL now)
{
tree[now].val=tree[now<<].val+tree[now<<|].val;
}
void Tree_down(LL now)
{
tree[now<<].flag+=tree[now].flag;
tree[now<<].val+=(tree[now].mid-tree[now].l+)*tree[now].flag;
tree[now<<|].flag+=tree[now].flag;
tree[now<<|].val+=(tree[now].r-tree[now].mid)*tree[now].flag;
tree[now].flag=;
}
void Tree_build(LL now,LL l,LL r)
{
tree[now].l=l;tree[now].r=r;
if(l==r)
{
tree[now].val=val[dfn[l]];
return ;
}
tree[now].mid=l+r>>;
Tree_build(now<<,l,tree[now].mid);
Tree_build(now<<|,tree[now].mid+,r);
Tree_up(now);
}
void Tree_change(LL now,LL l,LL r,LL x)
{ if(tree[now].l==l&&tree[now].r==r)
{
tree[now].flag+=x;
tree[now].val+=(r-l+)*x;
return ;
}
if(tree[now].flag) Tree_down(now);
if(tree[now].mid>=r) Tree_change(now<<,l,r,x);
else if(tree[now].mid<l) Tree_change(now<<|,l,r,x);
else
{
Tree_change(now<<,l,tree[now].mid,x);
Tree_change(now<<|,tree[now].mid+,r,x);
}
Tree_up(now);
}
LL Tree_query(LL now,int l,int r)
{
if(tree[now].l==l&&tree[now].r==r)
return tree[now].val;
if(tree[now].flag) Tree_down(now);
if(tree[now].mid>=r) return Tree_query(now<<,l,r);
else if(tree[now].mid<l) return Tree_query(now<<|,l,r);
else return Tree_query(now<<,l,tree[now].mid)+Tree_query(now<<|,tree[now].mid+,r);
} LL List_query(LL x,LL y)
{
LL ret=;
for(;top[x]!=top[y];x=dad[top[x]])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
ret+=Tree_query(,id[top[x]],id[x]);
}
if(deep[x]<deep[y]) swap(x,y);
ret+=Tree_query(,id[y],id[x]);
return ret;
} int if_,ch;
inline void read (LL &x)
{
if_=x=;ch=getchar();
for(;ch<''||ch>'';ch=getchar())
if(ch=='-') if_=;
for(;ch>=''&&ch<='';ch=getchar())
x=x*+ch-'';
if(if_) x=(~x)+;
} int main()
{
read(n); read(m);
for(LL i=;i<=n;i++)
read(val[i]);
for(LL i=;i<n;i++)
{
read(u); read(v);
ins(u,v),ins(v,u);
}
DFS(,,);DFS_(,);
Tree_build(,,n);
for(;m--;)
{
read(op);
if(op==)
{
read(u); read(w);
Tree_change(,id[u],id[u],w);
}
else if(op==)
{
read(u); read(w);
Tree_change(,id[u],id[u]+size[u]-,w);
}
else
{
read(u);
printf("%lld\n",List_query(u,));
}
}
return ;
}

洛谷——P3178 [HAOI2015]树上操作的更多相关文章

  1. 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)

    P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...

  2. 洛谷P3178 [HAOI2015]树上操作 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P3178 这道题目是一道树链剖分的模板题. 但是在解决这道问题的同事刷新了我的两个认识: 第一个认识是:树链剖分不光可以处理链, ...

  3. 洛谷P3178 [HAOI2015]树上操作

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  4. 洛谷P3178 [HAOI2015]树上操作(线段树)

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  5. 洛谷 P3178 [HAOI2015]树上操作

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  6. 洛谷 3178 [HAOI2015]树上操作

    [题解] 就是个树链剖分的模板题. #include<cstdio> #include<algorithm> #include<cstring> #define L ...

  7. P3178 [HAOI2015]树上操作

    P3178 [HAOI2015]树上操作 思路 板子嘛,其实我感觉树剖没啥脑子 就是debug 代码 #include <bits/stdc++.h> #define int long l ...

  8. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  9. BZOJ4033或洛谷3177 [HAOI2015]树上染色

    BZOJ原题链接 洛谷原题链接 很明显的树形\(DP\). 因为记录每个点的贡献很难,所以我们可以统计每条边的贡献. 对于每一条边,设边一侧的黑点有\(B_x\)个,白点有\(W_x\),另一侧黑点有 ...

随机推荐

  1. oracle 12c 关于wm_concat 的替换;LISTAGG

    之所以用到了wm_concat函数.是想到达这样的结果集. 转为这样的===========> 返回这样的数据,易与配合echarts的数据准备. 看上去十分的方便,但是遗憾的是,oracle极 ...

  2. .NET 将 .config 文件嵌入到程序集

    原文:.NET 将 .config 文件嵌入到程序集 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Iron_Ye/article/details/ ...

  3. Unity 性能优化(力荐)

    开始之前先分享几款性能优化的插件: 1.SimpleLOD : 除了同样拥有Mesh Baker所具有的Mesh合并.Atlas烘焙等功能,它还能提供Mesh的简化,并对动态蒙皮网格进行了很好的支持. ...

  4. 【Henu ACM Round#17 F】Upgrading Array

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 如果我们对某一个位置i操作两次的话. 显然结果就和操作一次一样. 因为第一次操作过后1..i这些数字就变成是互质的了. gcd为1. ...

  5. Java代码规范文档

    NOTE:以下部分为一个简要的编码规范,更多规范请参考 ORACLE 官方文档. 地址:http://www.oracle.com/technetwork/java/codeconventions-1 ...

  6. hibernate session.save()和session.persist()的区别

    save()需要返回一个Serialzable的实现类,因此执行这个方法时会马上插入到数据库 而persist()不会立即插入到数据库. "当我们封装一个长会话流程的时候,persist() ...

  7. Java Web乱码分析及解决方式(二)——POST请求乱码

    引言 GET请求的本质表现是将请求參数放在URL地址栏中.form表单的Method为GET的情况.參数会被浏览器默认编码,所以乱码处理方案是一样的. 对于POST请求乱码.解决起来要比GET简单.我 ...

  8. 一起talk C栗子吧(第八十一回:C语言实例--进程停止)

    各位看官们,大家好,上一回中咱们说的是进程相互排斥的样例,这一回咱们说的样例是:进程停止.闲话休提,言归正转. 让我们一起talk C栗子吧! 我们在前面的章回中介绍了怎样创建进程,只是没有介绍停止进 ...

  9. 独立python环境之virtualenv和virtualenvwrapper

    介绍 如果有一台測试机,多个人使用,有多个项目,不同项目可能python版本号不一样.须要的库不一样. 我们须要一个独立干净的python环境,互相隔离,互不影响. virtualenv能够帮我们解决 ...

  10. 127.0.0.1和localhost和本机IP三者的区别!

    1, 先来说下回送地址(Loopback Address): 回送地址是主机用于向自身发送通信的一个特殊地址(也就是一个特殊的目的地址).可以这么说:同一台主机上的两项服务若使用回送地址而非分配的主机 ...