欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ4034


题意概括

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个

操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

题解

  树链剖分。

  然后对于子树修改,我们可以考虑dfs序

  树链剖分也是一种dfs序。

  单点修改更简单,对于懒惰的我来说,这就是区间修改(少写了一个void 2333)

  询问几乎是基础的树剖了,沿着树链往上走就可以了。


代码

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long LL;
const int N=100005;
struct Gragh{
int cnt,y[N*2],nxt[N*2],fst[N];
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void add(int a,int b){
y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
}
}g;
int n,m,cnp=0;
int fa[N],son[N],size[N],depth[N],top[N],p[N],ap[N],outp[N];
LL v[N],t[N*4],add[N*4],w[N*4];
void Get_Gen_Info(int rt,int pre,int d){
size[rt]=1,fa[rt]=pre,depth[rt]=d,son[rt]=-1;
for (int i=g.fst[rt];i;i=g.nxt[i])
if (g.y[i]!=pre){
int s=g.y[i];
Get_Gen_Info(s,rt,d+1);
size[rt]+=size[s];
if (son[rt]==-1||size[s]>size[son[rt]])
son[rt]=s;
}
}
void Get_Top(int rt,int tp){
top[rt]=tp;
ap[p[rt]=++cnp]=rt;
if (son[rt]==-1){
outp[rt]=cnp;
return;
}
Get_Top(son[rt],tp);
for (int i=g.fst[rt];i;i=g.nxt[i]){
int s=g.y[i];
if (s!=fa[rt]&&s!=son[rt])
Get_Top(s,s);
}
outp[rt]=cnp;
}
void pushup(int rt){
int ls=rt<<1,rs=ls|1;
t[rt]=t[ls]+t[rs];
}
void build(int rt,int le,int ri){
w[rt]=ri-le+1;
add[rt]=0;
if (le==ri){
t[rt]=v[ap[le]];
return;
}
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
build(ls,le,mid);
build(rs,mid+1,ri);
pushup(rt);
}
void pushdown(int rt){
int ls=rt<<1,rs=ls|1;
LL &a=add[rt];
if (a){
t[ls]+=w[ls]*a,add[ls]+=a;
t[rs]+=w[rs]*a,add[rs]+=a;
a=0;
}
}
void update(int rt,int le,int ri,int xle,int xri,LL d){
if (le>xri||ri<xle)
return;
if (xle<=le&&ri<=xri){
t[rt]+=w[rt]*d,add[rt]+=d;
return;
}
pushdown(rt);
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
update(ls,le,mid,xle,xri,d);
update(rs,mid+1,ri,xle,xri,d);
pushup(rt);
}
LL query(int rt,int le,int ri,int xle,int xri){
if (le>xri||ri<xle)
return 0;
if (xle<=le&&ri<=xri)
return t[rt];
pushdown(rt);
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
return query(ls,le,mid,xle,xri)+query(rs,mid+1,ri,xle,xri);
}
LL Tquery(int a){
int f=top[a];
LL ans=0;
while (a){
ans+=query(1,1,n,p[f],p[a]);
a=fa[f],f=top[a];
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%lld",&v[i]);
g.clear();
for (int i=1,a,b;i<n;i++){
scanf("%d%d",&a,&b);
g.add(a,b);
g.add(b,a);
}
Get_Gen_Info(1,0,0);
Get_Top(1,1);
build(1,1,n);
for (int i=1;i<=m;i++){
int op,a,b;
scanf("%d",&op);
if (op==1){
scanf("%d%d",&a,&b);
update(1,1,n,p[a],p[a],b);
}
if (op==2){
scanf("%d%d",&a,&b);
update(1,1,n,p[a],outp[a],b);
}
if (op==3){
scanf("%d",&a);
printf("%lld\n",Tquery(a));
}
}
return 0;
}

  

BZOJ4034 [HAOI2015]树上操作 树链剖分的更多相关文章

  1. bzoj4034[HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6163  Solved: 2025[Submit][Stat ...

  2. BZOJ4034[HAOI2015]树上操作——树链剖分+线段树

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

  3. bzoj4034 [HAOI2015]树上操作——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4034 树剖裸题: 一定要注意 long long !!! update 的时候别忘了 pus ...

  4. 【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树

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

  5. bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4352  Solved: 1387[Submit][Stat ...

  6. P3178 [HAOI2015]树上操作 树链剖分

    这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开longlong!!!震惊!真的神奇. 题干: 题目描述 有一棵点数为 N 的树,以点 为根,且树点有边权.然后有 M 个操作, ...

  7. bzoj 4034: [HAOI2015]树上操作——树链剖分

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

  8. BZOJ 4034[HAOI2015]树上操作(树链剖分)

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

  9. [HAOI2015]树上操作-树链剖分

    #include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; #define mid ((l+r)>> ...

随机推荐

  1. 11. SpringBoot 之CRUD实例

    SpringBoot静态页路径,可直接通过URL访问的: /META-INF/resources /resources /static /public 而    5. /template 只和模板引擎 ...

  2. yolov3实践(一)

    很多博友看了我的第一篇博客yolo类检测算法解析——yolo v3,对其有了一定的认识和了解,但是并没有贴出代码和运行效果,略显苍白.因此在把篇博客理论的基础上,造就了第一篇实践文章,也就是本文.只要 ...

  3. configure编译选项

    1.rpath与rpath-link的区别 参考链接:http://blog.csdn.net/xph23/article/details/38157491 rpath 是 运行时候链接的库, rpa ...

  4. Database学习 - mysql 数据库 多表/复合/子 查询

    多表查询 多表查询,基本规则,通过两表有关联字段的进行条件匹配查询 内连接查询 方式一: SELECT 查看字段名[,查看字段名] FROM 一表名,二表名 WHERE 一/二表.字段 = 一/二表. ...

  5. maven插件的使用

    maven插件官网: https://maven.apache.org/plugins/index.html 1.JDK插件的使用 <build> <plugins> < ...

  6. SpringBoot整合Jest操作ES

    (1).添加依赖 <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</a ...

  7. Linux mmc framework1:软件架构

    [部分内容来自] http://www.wowotech.net/comm/mmc_framework_arch.html 1. 前言 由eMMC基础技术1:MMC简介中MMC.SD.SDIO的介绍可 ...

  8. suse系统开启ssh方法

    1.防火墙放开ssh服务 打开/etc/sysconfig/SuSEfirewall2 文件,FW_SERVICES_EXT_TCP="ssh"可以定义开放ssh的服务 2.编辑s ...

  9. WDS 三种模式

    (1)懒人模式(Lazy mode) 此模式下不需要填写对端的BSSID,本端AP的WDS连接作为被动连接,只需要对端填写了本端AP的BSSID即可,效果和桥接模式一样. (2)桥接模式(Bridge ...

  10. 12-关于DOM操作的相关案例

    1.模态框案例 需求: 打开网页时有一个普通的按钮,点击当前按钮显示一个背景图,中心并弹出一个弹出框,点击X的时候会关闭当前的模态框 代码如下: <!DOCTYPE html> <h ...