这题其实就是树剖裸题啊。

然后毒瘤选手由于上题树剖被卡到哭所以选择dfs序+树状数组。

不得不说简单的算法做出来更加难思考。然后网上的dalao们都一笔带过净说什么用两个树状数组维护就可以啦。

经过大半小时的思考,代码实现还是非常简单。

这个值得详细讲讲。

假如我们弄一个树状数组,然后维护的是x到根的sum(其实就是询问的答案嘛),先看第一个操作,单点修改,那么改了这个点,相当于把他这一整棵子树的答案都加上了d,由于用dfs序重新编号,可以发现子树中的点都是连续的,那么树状数组改段求段就可以用差分数组解决。

问题在于第二个操作,修改了整个子树,对每个节点y的影响是d*(dep[x]-dep[y]),那么非常难受,因为每个点改变的值和dep有关,并不相同,怎么办?绝佳的方法就是我们忽略dep的影响,用另一个树状数组维护d,那么问题又来了,x肯定不是时时相同的,虽然询问y的时候可以知道dep[y],但是dep[x]仍然不确定,为了可以确定,那么对于每次这种修改,我们就在第一个树状数组给它减去d*(dep[x]-1),这样一来,就把这个操作转化成增加x整个子树和x到根的路径上的点,那么对于每个点,增加的数就变成d*dep[y],那么求解的时候,就可以心安理得的用第一个树状数组的值+第二个树状数组的值*d了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;int n,m;struct node
{int x,y,next;
}a[210000];int len,last[110000];
void ins(int x,int y)
{len++;a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;
}int z,dep[110000],l[110000],r[110000];
void dfs(int x,int f)
{l[x]=++z;for(int k=last[x];k;k=a[k].next){int y=a[k].y;if(y!=f)dep[y]=dep[x]+1, dfs(y,x);}r[x]=z;
}//---------init-----------------

LL s[2][110000];
int lowbit(int x){return x&-x;}
void change(int w,int x,LL k)
{while(x<=n){s[w][x]+=k;x+=lowbit(x);}
}
LL getsum(int w,int x)
{LL ret=0;while(x>=1){ret+=s[w][x];x-=lowbit(x);}return ret;
}//-----------bit--------------

LL point[110000];
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%lld",&point[i]);len=0;memset(last,0,sizeof(last));int x,y;for(int i=1;i<n;i++){scanf("%d%d",&x,&y);ins(x,y);ins(y,x);}z=0;dep[1]=1;dfs(1,0);//initfor(int i=1;i<=n;i++)change(0,l[i],point[i]), change(0,r[i]+1,-point[i]);int op;LL d;for(int i=1;i<=m;i++){scanf("%d",&op);if(op==1){scanf("%d%lld",&x,&d);change(0,l[x],d);change(0,r[x]+1,-d);}else if(op==2){scanf("%d%lld",&x,&d);change(0,l[x],-d*(dep[x]-1));change(0,r[x]+1,d*(dep[x]-1));change(1,l[x],d);change(1,r[x]+1,-d);}else{scanf("%d",&x);printf("%lld\n", getsum(0,l[x]) + dep[x]*getsum(1,l[x]) );}}return 0;
}

转载于:https://www.cnblogs.com/AKCqhzdy/p/8490480.html

bzoj4034: [HAOI2015]树上操作相关推荐

  1. P3178 [HAOI2015]树上操作

    P3178 [HAOI2015]树上操作 题意: 题解: 这已经是很裸的树链剖分了... 直接套模板 代码: #include<cmath> #include<cstdio> ...

  2. BZOJ 4043 [HAOI2015]树上操作 dfs序 线段树

    $ \Rightarrow $ 戳我进BZOJ原题 $ \Rightarrow $ 戳我进洛谷原题 [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 25 ...

  3. bzoj 4034: [HAOI2015]树上操作(树链剖分+线段树区间更新)

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 4981  Solved: 1603 [Submit][St ...

  4. [HAOI2015]树上操作

    题目大意: 给你一棵n个点的树,以1为根,每个点都有一个点权,要求进行如下操作: 1.将x这个点的点权加上a: 2.将以x这个点为根的子树中每个点的点权加上a: 3.查询从x到根的路径的点权和. 思路 ...

  5. [BZOJ 4034][HAOI2015]树上操作(欧拉序列+线段树)

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

  6. luogu P3178 [HAOI2015]树上操作

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

  7. 省选专练HAOI2015树上操作

    题如其名 树链剖分板子题 #include<bits/stdc++.h> using namespace std; #define lc (p<<1) #define rc ( ...

  8. BZOJ4034 树上操作

    目录 BZOJ4034 树上操作 题解 code BZOJ4034 树上操作 题目传送门 题解 裸的树剖,写的时候注意细节即可. code #include <bits/stdc++.h> ...

  9. [BZOJ4033][HAOI2015]树上染色

    4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2108  Solved: 901 [Submit][Sta ...

最新文章

  1. 3D Point Cloud Library install
  2. Apache简单配置(4)搭建Discuz 7.0.0论坛
  3. 一份非常详尽的 Objective-C 到 Swift 的迁移指南
  4. 判断条件为空时需要注意
  5. DevOps笔记-08:DevOps追求的根本目标:多快好省
  6. linux下git分支管理,git远程分支管理
  7. ARM(IMX6U)ARM Cortex-A7中断系统(GPIO按键中断驱动蜂鸣器)
  8. google earth pro 64位_七彩虹秀精准刀工!iGame RTX 3060 Ti Advanced OC评测:烤机3小时64度...
  9. 讨论帖:比特币中的SHA256算法的实现与标准的SHA256算法实现是否相同?
  10. C++共享内存类封装
  11. 不简单的工厂:实际体验 .NET Core 2.1 新生物 HttpClientFactory
  12. python 图像压缩 jpeg_smally:批量无损压缩JPG和PNG
  13. sklearn——一元线性回归
  14. CVPR2021投稿要求
  15. 49、建筑外墙上防火墙的设置
  16. 【代码实践】使用CLIP做一些多模态的事情
  17. [生存志] 第130节 司马著史记
  18. 控制过滤器Filter执行顺序
  19. 时间序列之ARIMA模型原理
  20. 小鲲Python嘎嘎炫~day2

热门文章

  1. 使用个推的时候出现Installation error: INSTALL_FAILED_DUPLICATE_PERMISSION
  2. Linux下Nginx+PHP+MySQL配置(图)
  3. ORA-01994 故障一例
  4. AjaxControlToolkit HoverMenuExtender 控件演示
  5. 终于知道如何才能取得HtmlEditor里的数据了
  6. Leetcode 172. 阶乘后的零 解题思路及C++实现
  7. 数据结构源码笔记(C语言):链接队列
  8. 修改mysql字符编码出现Job failed to start解决办法
  9. java格式化double_java – 格式化double以省略不必要的“.0”,永远不会关闭
  10. ServletContext对象详解