[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 为根的子树中所 ...
随机推荐
- 160302、细聊分布式ID生成方法
一.需求缘起 几乎所有的业务系统,都有生成一个记录标识的需求,例如: (1)消息标识:message-id (2)订单标识:order-id (3)帖子标识:tiezi-id 这个记录标识往往就是数据 ...
- JAR包中的MANIFEST.MF文件详解以及编写规范
参考百度百科的解释如下: http://baike.baidu.com/item/MANIFEST.MF MANIFEST.MF:这个 manifest 文件定义了与扩展和包相关的数据.单词“mani ...
- Oracle Schema Objects(Schema Object Storage And Type)
One characteristic of an RDBMS is the independence of physical data storage from logical data struct ...
- Fully qualified name FQCN
Fully qualified name - Wikipedia https://en.wikipedia.org/wiki/Fully_qualified_name In computer prog ...
- python celery rabbitmq--- pypi image from ustc
https://lug.ustc.edu.cn/wiki/mirrors/help/pypi 那么为啥要用celery ?(http://xiaorui.cc/2014/11/16/celery-ra ...
- Storm-源码分析- Messaging (backtype.storm.messaging)
先定义两个接口和一个类 TaskMessage类本身比较好理解, 抽象storm的message格式 对于IContext, 注释也说了, 定义messaging plugin, 通过什么渠道去发送m ...
- Ubuntu 下 mysql 卸载后重安装时遇到的问题
卸载mysql报错解决方法1 dpkg: error processing mysql-server (--configure): dependency problems - leaving unco ...
- Spark Standalone Mode 多机启动 -- 分布式计算系统spark学习(二)(更新一键启动slavers)
捣鼓了一下,先来个手动挡吧.自动挡要设置ssh无密码登陆啥的,后面开搞. 一.手动多台机链接master 手动链接master其实上篇已经用过. 这里有两台机器: 10.60.215.41 启动mas ...
- GNU Screen使用入门
前些天开始学习使用GNU Screen程序,发现这个工具在管理服务器时候确实挺方便的,于是写一篇文章总结一下,顺便介绍Screen的基本使用方法. 简介 GNU Screen是 一个基于文本的全屏窗口 ...
- python爬虫系列(2)—— requests和BeautifulSoup
本文主要介绍python爬虫的两大利器:requests和BeautifulSoup库的基本用法. 1. 安装requests和BeautifulSoup库 可以通过3种方式安装: easy_inst ...