[HAOI2015]T2
【题目描述】
有一棵点数为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)。
【输出格式】
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
【样例输入】
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
【样例输出】
6
9
13
【提示】
对于30%的数据,N,M<=1000
对于50%的数据,N,M<=100000且数据随机。
对于100%的数据,N,M<=100000,且所有输入数据的绝对值都不会超过10^6。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long LL;
const LL maxn=;
inline LL read(){
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
vector<LL> to[maxn];
LL N,M;
LL a[maxn];
LL dep[maxn],fa[maxn],son[maxn],top[maxn],siz[maxn],id[maxn];
LL val[maxn];
LL num;
inline void dfs1(LL rt,LL fath,LL deep){
dep[rt]=deep; siz[rt]=; fa[rt]=fath;
for(LL i=;i<to[rt].size();i++){
LL y=to[rt][i];
if(y!=fa[rt]){
dfs1(y,rt,deep+);
siz[rt]+=siz[y];
if(siz[son[rt]]<siz[y]) son[rt]=y;
}
}
}
inline void dfs2(LL rt,LL tp){
top[rt]=tp; id[rt]=++num;
if(son[rt]!=) dfs2(son[rt],tp);
for(LL i=;i<to[rt].size();i++){
LL y=to[rt][i];
if(y!=fa[rt]&&y!=son[rt]){
dfs2(y,y);
}
}
}
struct node{
LL l,r;
LL sum,lazy;
}tree[maxn*];
inline void build(LL rt,LL l,LL r){
tree[rt].l=l; tree[rt].r=r;
if(l==r){
tree[rt].sum=val[l];
tree[rt].lazy=;
return ;
}
LL mid=(l+r)>>;
build(rt<<,l,mid); build(rt<<|,mid+,r);
tree[rt].sum=tree[rt<<].sum+tree[rt<<|].sum;
}
inline void update_son(LL rt){
LL d=tree[rt].lazy;
if(d!=){
tree[rt<<].sum+=(tree[rt<<].r-tree[rt<<].l+)*d;
tree[rt<<|].sum+=(tree[rt<<|].r-tree[rt<<|].l+)*d;
tree[rt<<].lazy+=d; tree[rt<<|].lazy+=d;
tree[rt].lazy=;
}
}
inline void change(LL rt,LL l,LL r,LL delta){
if(l<=tree[rt].l&&tree[rt].r<=r){
tree[rt].sum+=(tree[rt].r-tree[rt].l+)*delta;
tree[rt].lazy+=delta;
return ;
}
update_son(rt);
LL mid=(tree[rt].l+tree[rt].r)>>;
if(l<=mid) change(rt<<,l,r,delta);
if(mid+<=r) change(rt<<|,l,r,delta);
tree[rt].sum=tree[rt<<].sum+tree[rt<<|].sum;
}
inline LL query(LL rt,LL l,LL r){
if(l<=tree[rt].l&&tree[rt].r<=r){
return tree[rt].sum;
}
update_son(rt);
LL ans=;
LL mid=(tree[rt].l+tree[rt].r)>>;
if(l<=mid) ans+=query(rt<<,l,r);
if(mid+<=r) ans+=query(rt<<|,l,r);
return ans;
}
inline void ASK(LL x){
LL tp=top[x],ans=;
while(x!=&&tp!=){
ans+=query(,id[tp],id[x]);
x=fa[tp]; tp=top[x];
}
printf("%lld\n",ans);
}
int main(){
N=read(); M=read();
for(LL i=;i<=N;i++) a[i]=read();
for(LL i=,u,v;i<=N-;i++){
u=read(); v=read();
to[u].push_back(v); to[v].push_back(u);
}
dis[]=a[];
dfs1(,,); dfs2(,);
for(LL i=;i<=N;i++) val[id[i]]=a[i];
build(,,num);
for(LL i=,kin;i<=M;i++){
kin=read();
if(kin==){
LL x=read(),d=read();
change(,id[x],id[x],d);
}
else if(kin==){
LL x=read(),d=read();
change(,id[x],id[x]+siz[x]-,d);
}
else if(kin==){
LL x=read();
ASK(x);
}
}
return ;
}
[HAOI2015]T2的更多相关文章
- bzoj4034: [HAOI2015]T2
		
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 2684 Solved: 843 Description 有一 ...
 - bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
		
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
 - Bzoj 4034: [HAOI2015]T2  树链剖分,子树问题,dfs序
		
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1841 Solved: 598[Submit][Status] ...
 - BZOJ 4034: [HAOI2015]T2( 树链剖分 )
		
树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...
 - bzoj 4034: [HAOI2015]T2
		
4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...
 - 数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2
		
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
 - BZOJ4034——[HAOI2015]T2
		
1.题目大意:用一个数据结构支持树的点修改和子树修改.树上路径和 2.分析:树链剖分裸题 #include <cstdio> #include <cstdlib> #inclu ...
 - BZOJ 4034 [HAOI2015]T2(树链剖分)
		
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4034 [题目大意] 有一棵点数为 N 的树,以点 1 为根,且树点有边权. 有 M 个 ...
 - [BZOJ4034] [HAOI2015] T2 (树链剖分)
		
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...
 
随机推荐
- WHICH ONE IS BETTER FOR NEWBIE?
			
DROP PROCEDURE IF EXISTS w_array; DELIMITER /w/ )) BEGIN ) DO SET @w = LOCATE(',', w_arr); ); SET @w ...
 - __destruct()析构函数的执行时刻 __construct()构造函数传入参数 构造函数与后台登录安全
			
<?php class test_construct_avg { function __construct($input = '') { $this->input = $input; } ...
 - python学习笔记(四)— 补充
			
函数return多个值 函数如果有多个return值,那么会生成一个元组里面 def hello(a,b,c,d): return a,b,c,d res =hello('aa','cc','dd', ...
 - SecureCRT图形界面
			
一般的咱们用这个工具连接服务器啥的都是命令行模式的,其实他也可以连接图形界面 一.Xmanager SecureCRT连接图形界面的话必须要有 Xmanager 工具的配合才行,SecureCRT显示 ...
 - python中yield使用
			
16.yield使用 列表推导与生成器表达式 当我们创建了一个列表的时候,就创建了一个可以迭代的对象: >>> squares=[n*n for n in range(3)] ...
 - 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
			
本文背景: 在编程中,很多Windows或C++的内存函数不知道有什么区别,更别谈有效使用:根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过简单的总结描述,结合实例来阐明这个机制. 本 ...
 - java_基础——用代码编译.java文件+加载class文件
			
[本文介绍] 本文不是深入理解和使用java编译器,只是在代码里编译.java文件的helloWorld.这种技术还是蛮有意思的,说不定在将来的某些只能化项目会运用到!^_^ [简单编译的流程] [j ...
 - dbms_advisor 手动生成段顾问建议!
			
执行包需要dbms_advisor权限: sys@ORCL> grant advisor to u1; 授权成功. 创建段顾问任务,指定create_task的advisor_name参数为“段 ...
 - 关于softnet的加密硬件狗  也就是所谓的赛孚耐
			
SuperDog-R-2.2.1.iso 上面那个文件就是光盘里面的东西.你买了他们的产品 自然后带着这个玩意. 按照默认路径安装一下. 安装完毕如下图:
 - [Windows Powershell]-学习笔记(5)
			
Powershell自动化变量 Powershell 自动化变量 是那些一旦打开Powershell就会自动加载的变量,或者说是运行是变量. 这些变量一般存放的内容包括 用户信息:例如用户的根目录$h ...