传送门
写在前面:大晚上写题解,明天上午去看电影,可以的~~
思路:比较裸的树链剖分,比起普通的链剖,这里加了一步对子树(包括自己)的权值修改,这其实很简单,因为我们dfs时任一个子树的区间[L,R]在线段树上都是连续的,而且显然L记录该子树根的权值,R记录子树最右边的点的权值,可以对整棵子树dfs后得到,接下来就是打上lazy标记的线段树操作了
注意:
计算答案一定要开longlong,而且有些中间步骤如果是用int计算一定要加“强制类型转换”
代码:

#include"bits/stdc++.h"
#define LL long long
using namespace std;
int n,m,opr,x,y,tot,cnt;
int pre[100010],w[100010],top[100010],fa[100010],son[100010],first[100010],dep[100010],siz[100010],L[100010],R[100010];
struct os
{int u,v,next;
}e[200010];
struct node
{LL sum,lazy;
}tree[800010];
void pushdown(int now,int begin,int end)
{int mid=(begin+end)>>1;tree[now<<1].sum+=(mid-begin+1)*tree[now].lazy;tree[now<<1].lazy+=tree[now].lazy;tree[now<<1|1].sum+=(end-mid)*tree[now].lazy;tree[now<<1|1].lazy+=tree[now].lazy;tree[now].lazy=0;
}
void add(int x,int y)
{e[++tot].u=x;e[tot].v=y;e[tot].next=first[x];first[x]=tot;
}
void dfs1(int now)
{siz[now]=1;for (int i=first[now];i;i=e[i].next)if (e[i].v!=fa[now]){dep[e[i].v]=dep[now]+1;fa[e[i].v]=now;dfs1(e[i].v);if (siz[e[i].v]>siz[son[now]]) son[now]=e[i].v;siz[now]+=siz[e[i].v];}
}
void dfs2(int now,int tp)
{L[now]=++cnt;pre[cnt]=now;top[now]=tp;if (son[now]) dfs2(son[now],tp);for (int i=first[now];i;i=e[i].next)if (e[i].v!=fa[now]&&e[i].v!=son[now])dfs2(e[i].v,e[i].v);R[now]=cnt;
}
void build(int now,int begin,int end)
{if (begin==end) {tree[now].sum=w[pre[end]];return;}int mid=(begin+end)>>1;build(now<<1,begin,mid);build(now<<1|1,mid+1,end);tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
}
void update(int now,int begin,int end,int l,int r,int num)
{if (l<=begin&&end<=r) {tree[now].lazy+=num;tree[now].sum+=(LL)num*(LL)(end-begin+1);return;}pushdown(now,begin,end);int mid=(begin+end)>>1;if (mid>=l) update(now<<1,begin,mid,l,r,num);if (mid<r) update(now<<1|1,mid+1,end,l,r,num);tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
}
LL get_sum(int now,int begin,int end,int l,int r)
{if (l<=begin&&end<=r) return tree[now].sum;pushdown(now,begin,end);int mid=(begin+end)>>1;LL ans=0;if (mid>=l) ans+=get_sum(now<<1,begin,mid,l,r);if (mid<r) ans+=get_sum(now<<1|1,mid+1,end,l,r);return ans;
}
LL solve(int l,int r)
{int f1=top[l],f2=top[r];LL ans=0;while (f1!=f2){if (dep[f1]<dep[f2]) swap(f1,f2),swap(l,r);ans+=get_sum(1,1,cnt,L[f1],L[l]);l=fa[f1];f1=top[l];}if (dep[l]>dep[r]) swap(l,r);ans+=get_sum(1,1,cnt,L[l],L[r]);return ans;
}
main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++) scanf("%d",&w[i]);for (int i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);dfs1(1);dfs2(1,1);build(1,1,cnt);while (m--){scanf("%d",&opr);if (opr==3){scanf("%d",&x);printf("%lld\n",solve(x,1));}else{scanf("%d%d",&x,&y);if (opr==1)update(1,1,cnt,L[x],L[x],y);else update(1,1,cnt,L[x],R[x],y);}}
}

【BZOJ4034】T2,树链剖分练习相关推荐

  1. BZOJ 4034 [HAOI2015]T2 树链剖分

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

  2. BZOJ 4034: [HAOI2015]T2 树链剖分

    4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...

  3. NOI2015 Day1 T2 软件包管理器 树链剖分

    NKOJ3423 NOI2015 软件包管理器 时间限制 : 20000 MS 空间限制 : 524288 KB 问题描述 Linux用户和OS X用户一定对软件包管理器不会陌生.通过软件包管理器,你 ...

  4. P1505 [国家集训队]旅游 树链剖分

    题目链接 题意:树上更新某一点权值,更新两点简单路径权值,查询最大,最小,和 思路:思路应该比较简单,就是树链剖分后用线段树维护区间最大最小以及区间和. 但是本题比较特殊的是给的边权,转化为点权即可. ...

  5. [树链剖分][SDOI 2011]染色,Housewife Wind

    文章目录 T1:Housewife Wind 题目 题解 code T2:染色 题目 题解 code 今天选择写这篇博客主要是为了告诉大家一个道理,数组比vectorvectorvector快太多了, ...

  6. [树链剖分]hihocoder1883

    描述 有一个无向图,有n个点,m1条第一类边和m2条第二类边.第一类边有边权,第二类边无边权.请为第二类的每条边定义一个边权,使得第二类边可能全部出现在该无向图的最小生成树上,同时要求第二类边的边权总 ...

  7. 【ZJOI2008】树的统计(树链剖分)

    传送门 Solution: 就是树链剖分入门题啦~ // luogu-judger-enable-o2 #include<bits/stdc++.h> #define N 30005 #d ...

  8. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  9. 【模板】树链剖分 P3384

    题目链接 //部分转自:https://www.luogu.org/problemnew/solution/P3384 初学树链剖分,感觉这个模板题还是容易理解的,但是实在是码量很大的. 知识点: 重 ...

最新文章

  1. java下列语句正确的是_下列Java语句中,不正确的一项是( )。
  2. 第十六周程序阅读(7)
  3. 某全球零售客户:上马容器云 驾驭线上业务
  4. Access导入MDB文件
  5. mysql内存体系结构_Innodb存储引擎的体系架构之内存
  6. 用JavaScript往DIV动态添加内容
  7. 掌握新手学车技巧对于新手来说是非常重要的
  8. linux 如何产生so文件,printf()函数 【转】Linux下gcc编译生成动态链接库*.so文件并调用它(2)...
  9. 【OpenCV 例程200篇】62. 图像锐化——钝化掩蔽
  10. python截取指定字符串_python 正则匹配获取指定多个词的在字符串(句子/段落)索引位置...
  11. 信息学奥赛一本通(1183:病人排队)
  12. java确认rabbitmq_RabbitMQ的消息确认模式
  13. ip=request.servervariables(Remote_Addr)获得ip显示::1
  14. Linux基础知识-文件管理
  15. 读书感受 之《活着》
  16. 国外英文版云购夺宝网站项目开发制作代码解析
  17. Verilog 语法小结
  18. Bitvise Tunnelier 安装教程及报错处理
  19. 共享服务器文件溢出,文件共享软件Samaba中发现缓冲区溢出漏洞
  20. 随心情更新的学习笔记——JS代码之栈的佩兹的糖果盒

热门文章

  1. creportctrl 排序_witclient 智能客户端
  2. 参加计算机俱乐部的英语怎么说,参加象棋俱乐部用英语怎么说
  3. androidh5混合开发_Android H5混合开发(3):原生Android项目里嵌入Cordova
  4. python购物车结算_python购物车-基础版本
  5. Linux shell中在vim打开的文件中查找关键字
  6. dubbo分布式系统链路追踪_zipkin
  7. python怎么设置回文数_python如何写一个函数判断回文数?
  8. xampp for mac mysql_【XAMPP和Xampp For Mac哪个好用】XAMPP和Xampp For Mac对比-ZOL下载
  9. mysql alter event_MYSQL ALTER EVENT介绍
  10. elisa标准曲线怎么做_Curve Expert软件绘制ELISA标准曲线流程 | 每日生物评论