4034. [HAOI2015]树上操作【树链剖分】
Description
Input
Output
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
Sample Input
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
Sample Output
9
13
HINT
对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不会超过 10^6 。
一道裸的树剖却因为建树时候的sb错误搞了半天
不想说什么(不过这个题好像会炸int)
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #define LL long long
- #define MAXN (100000+50)
- using namespace std;
- LL Tree[MAXN];
- LL T_num[MAXN];
- LL Depth[MAXN];
- LL Father[MAXN];
- LL Sum[MAXN];
- LL Son[MAXN];
- LL Top[MAXN];
- LL a[MAXN];
- LL n,m,u,v,sum;
- LL head[MAXN],num_edge;
- struct node1
- {
- LL val;
- LL add;
- } Segt[MAXN*];
- struct node2
- {
- LL to;
- LL next;
- } edge[MAXN*];
- void add(LL u,LL v)
- {
- edge[++num_edge].to=v;
- edge[num_edge].next=head[u];
- head[u]=num_edge;
- }
- void Dfs1(LL x)
- {
- Sum[x]=;
- Depth[x]=Depth[Father[x]]+;
- for (LL i=head[x]; i!=; i=edge[i].next)
- if (edge[i].to!=Father[x])
- {
- Father[edge[i].to]=x;
- Dfs1(edge[i].to);
- Sum[x]+=Sum[edge[i].to];
- if (Son[x]== || (Sum[Son[x]]<Sum[edge[i].to]))
- Son[x]=edge[i].to;
- }
- }
- void Dfs2(LL x,LL tp)
- {
- T_num[x]=++sum;
- Tree[sum]=a[x];
- Top[x]=tp;
- if (Son[x])
- Dfs2(Son[x],tp);
- for (LL i=head[x]; i!=; i=edge[i].next)
- if (edge[i].to!=Son[x] && edge[i].to!=Father[x])
- Dfs2(edge[i].to,edge[i].to);
- }
- void Pushdown(LL node,LL l,LL r)
- {
- if (Segt[node].add!=)
- {
- LL mid=(l+r)/;
- Segt[node*].val+=Segt[node].add*(mid-l+);
- Segt[node*+].val+=Segt[node].add*(r-mid);
- Segt[node*].add+=Segt[node].add;
- Segt[node*+].add+=Segt[node].add;
- Segt[node].add=;
- }
- }
- void Build(LL node,LL l,LL r)
- {
- if (l==r)
- Segt[node].val=Tree[l];
- else
- {
- LL mid=(l+r)/;
- Build(node*,l,mid);
- Build(node*+,mid+,r);
- Segt[node].val=Segt[node*].val+Segt[node*+].val;
- }
- }
- void Update(LL node,LL l,LL r,LL l1,LL r1,LL k)
- {
- if (l>r1 || r<l1)
- return;
- if (l1<=l && r<=r1)
- {
- Segt[node].val+=(r-l+)*k;
- Segt[node].add+=k;
- return;
- }
- Pushdown(node,l,r);
- LL mid=(l+r)/;
- Update(node*,l,mid,l1,r1,k);
- Update(node*+,mid+,r,l1,r1,k);
- Segt[node].val=Segt[node*].val+Segt[node*+].val;
- }
- LL Query(LL node,LL l,LL r,LL l1,LL r1)
- {
- if (l>r1 || r<l1)
- return ;
- if (l1<=l && r<=r1)
- return Segt[node].val;
- Pushdown(node,l,r);
- LL mid=(l+r)/;
- return Query(node*,l,mid,l1,r1)+Query(node*+,mid+,r,l1,r1);
- }
- LL Get(LL x)
- {
- LL ans=;
- while (x!=)
- {
- ans+=Query(,,n,T_num[Top[x]],T_num[x]);
- x=Father[Top[x]];
- }
- return ans;
- }
- int main()
- {
- scanf("%lld%lld",&n,&m);
- for (LL i=; i<=n; ++i)
- scanf("%lld",&a[i]);
- for (LL i=; i<=n-; ++i)
- {
- scanf("%lld%lld",&u,&v);
- add(u,v);
- add(v,u);
- }
- Dfs1();
- Dfs2(,);
- Build(,,n);
- for (LL i=; i<=m; ++i)
- {
- LL p,x,y;
- scanf("%lld",&p);
- if (p==)
- {
- scanf("%lld%lld",&x,&y);
- Update(,,n,T_num[x],T_num[x],y);
- }
- if (p==)
- {
- scanf("%lld%lld",&x,&y);
- Update(,,n,T_num[x],T_num[x]+Sum[x]-,y);
- }
- if (p==)
- {
- scanf("%lld",&x);
- printf("%lld\n",Get(x));
- }
- }
- }
4034. [HAOI2015]树上操作【树链剖分】的更多相关文章
- bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4352 Solved: 1387[Submit][Stat ...
- bzoj 4034: [HAOI2015]树上操作——树链剖分
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
- BZOJ 4034[HAOI2015]树上操作(树链剖分)
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点 ...
- bzoj4034[HAOI2015]树上操作 树链剖分+线段树
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 6163 Solved: 2025[Submit][Stat ...
- 【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树
[BZOJ4034][HAOI2015]树上操作 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 ...
- BZOJ4034 [HAOI2015]树上操作 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...
- P3178 [HAOI2015]树上操作 树链剖分
这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开longlong!!!震惊!真的神奇. 题干: 题目描述 有一棵点数为 N 的树,以点 为根,且树点有边权.然后有 M 个操作, ...
- BZOJ4034[HAOI2015]树上操作——树链剖分+线段树
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都 ...
- bzoj4034 [HAOI2015]树上操作——树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4034 树剖裸题: 一定要注意 long long !!! update 的时候别忘了 pus ...
- [HAOI2015]树上操作-树链剖分
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; #define mid ((l+r)>> ...
随机推荐
- MSSQL存储过程实现拼接sql的注意点
这里我昨天碰到的问题就是执行一段根据变量tableName对不同的表进行字段状态的更改.由于服务器原因,我不能直接在数据访问层写SQL,所以只好抽离出来放到存储过程里面. 这里就出现了一个问题,我花费 ...
- [C语言] 数据结构-逻辑结构和物理结构
数据结构:相互之间存在一种或多种特定关系的数据元素的集合 1.数据结构分为逻辑结构和物理结构 集合结构:集合结构中的数据元素除了同属于一个集合外,他们之间没有其他关系 线性结构:线性结构中的数据元素之 ...
- 利用CEF山寨一个翻译器
起因 在某些情况下,有将从某种类型的语言翻译成另一种类型语言的需求.比如在生成实体时,可能需要将中文名称转换成英文.于是利用CEFSharp山寨了一个翻译器.效果图如下: CEF简介 CEF全称为Ch ...
- 使用tcmalloc替换系统的malloc
https://blog.csdn.net/educast/article/details/79166553?utm_source=blogxgwz0 今天对服务器进行压测,模拟的请求量到4万次/分的 ...
- Effective C++ Placement new
#include <iostream> #include <cstdlib> using namespace std; class Card { private: int m_ ...
- 基于Vue实现图片在指定区域内移动
当图片比要显示的区域大时,需要将多余的部分隐藏掉,我们可以通过绝对定位来实现,并通过动态修改图片的left值和top值从而实现图片的移动.具体实现效果如下图,如果我们移动的是div 实现思路相仿. 此 ...
- javascript数组元素全排列
多个数组(数量不定)例如三个数组 {a,b} {1,2} {d}排列组合后为a,1,da,2,db,1,db,2,d是js的算法哦 var arr = [["a","b& ...
- Laravel 支付宝异步通知 419报错
支付宝在支付是有服务器通知和网页通知,一个在前端展示,一个在后台操作, laravel框架自带csrf_token验证. 所以我们需要把支付的路由跳过验证 可以在中间键的csrf配置中更改
- Android EditText方框验证码 短信验证码攻略
本文由xiawe_i提供. xiawe_i的博客地址是: http://www.jianshu.com/u/fa9f03a240c6 项目中有这样一个需求: 验证码页是四个方框,输入验证码方框颜色改变 ...
- Android 后台线程,timertask实现定期更新时间
简述:这是一类定时功能的原型,用来在后台线程中运行一些定时的服务,比如定时修改时间 知识点: 1. Android多线程的消息通信(handler) 2. Java中时间的获取,以及String的格式 ...