1963. [HAOI 2015] 树上操作

★★★☆   输入文件:haoi2015_t2.in   输出文件:haoi2015_t2.out   简单对比
时间限制:1 s   内存限制:256 MB

【题目描述】

有一棵点数为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<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
#define LL long long
const int maxn=;
int n,m,cot=;
LL a[maxn];
vector<int> v[maxn];
int size[maxn];
int son[maxn];
int fa[maxn];
int top[maxn];
int dfn[maxn];
int pos[maxn];
int dep[maxn];
int en[maxn];
LL ls[maxn<<],rs[maxn<<],lz[maxn<<],sum[maxn<<];
int cnt=;
void Dfs(int rt){
size[rt]=;
for(int i=;i<v[rt].size();i++)
if(!size[v[rt][i]]){
int to=v[rt][i];
dep[to]=dep[rt]+;
fa[to]=rt;
Dfs(to);
size[rt]+=size[to];
if(size[son[rt]]<size[to]) son[rt]=to;
}
}
void Dfs(int rt,int tp){
top[rt]=tp;
dfn[++cnt]=rt;
pos[rt]=cnt;
if(son[rt]) Dfs(son[rt],tp);
for(int i=;i<v[rt].size();i++)
if(!top[v[rt][i]])
Dfs(v[rt][i],v[rt][i]);
en[rt]=cnt;
}
int Build(int l,int r){
int rt=++cot;
if(l==r){
sum[rt]=a[dfn[l]];
return rt;
}
int mid=(l+r)>>;
ls[rt]=Build(l,mid);
rs[rt]=Build(mid+,r);
sum[rt]=sum[ls[rt]]+sum[rs[rt]];
return rt;
}
void Push_down(int rt,int l,int r){
int mid=(l+r)>>;
lz[ls[rt]]+=lz[rt];
lz[rs[rt]]+=lz[rt];
sum[ls[rt]]+=lz[rt]*(mid-l+);
sum[rs[rt]]+=lz[rt]*(r-mid);
lz[rt]=; }
LL Add(int rt,int l,int r,int s,int t,int qx){
if(s>r||t<l) return ;
if(s<=l&&r<=t){
sum[rt]+=qx*1ll*(r-l+);
lz[rt]+=qx;
return ;
}
Push_down(rt,l,r);
int mid=(l+r)>>;
Add(ls[rt],l,mid,s,t,qx);Add(rs[rt],mid+,r,s,t,qx);
sum[rt]=sum[ls[rt]]+sum[rs[rt]];
}
LL Sum(int rt,int l,int r,int s,int t){
if(s>r||t<l) return ;
if(s<=l&&r<=t) return sum[rt];
Push_down(rt,l,r);
int mid=(l+r)>>;
return Sum(ls[rt],l,mid,s,t)+Sum(rs[rt],mid+,r,s,t);
}
LL LCA_dis(int x,int y){
LL res=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res+=Sum(,,n,pos[top[x]],pos[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res+=Sum(,,n,pos[x],pos[y]);
return res;
}
int main()
{
freopen("haoi2015_t2.in","r",stdin);
freopen("haoi2015_t2.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
for(int i=;i<n;i++) {
int x,y;scanf("%d%d",&x,&y);
v[x].push_back(y);v[y].push_back(x);
}
Dfs();Dfs(,);Build(,n);
while(m--){
int opt;scanf("%d",&opt);
if(opt==){
int x,aa;scanf("%d%d",&x,&aa);
Add(,,n,pos[x],pos[x],aa);
}
if(opt==){
int x,aa;
scanf("%d%d",&x,&aa);
Add(,,n,pos[x],en[x],aa);
}
if(opt==){
int x;scanf("%d",&x);
printf("%lld\n",LCA_dis(x,));
}
}
return ;
}

cogs 1963. [HAOI 2015] 树上操作 树链剖分+线段树的更多相关文章

  1. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  2. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  3. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  4. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  5. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

  6. 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树

    正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...

  7. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

  8. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  9. fzu 2082 过路费 (树链剖分+线段树 边权)

    Problem 2082 过路费 Accept: 887    Submit: 2881Time Limit: 1000 mSec    Memory Limit : 32768 KB  Proble ...

随机推荐

  1. HDU 2454"Degree Sequence of Graph G"(度序列可图性判断)

    传送门 参考资料: [1]:图论-度序列可图性判断(Havel-Hakimi定理) •题意 给你 n 个非负整数列,判断这个序列是否为可简单图化的: •知识支持 握手定理:在任何无向图中,所有顶点的度 ...

  2. 【git】Git回退代码到指定版本

    1. 查看所有的历史版本,获取你git的某个历史版本的id, git log2. 回退本地代码库:git reset --hard ID3. 推送到远程服务器:git push -f -u origi ...

  3. P1062 差K素数对

    题目描述 给你两个数 n 和 k ,请求出所有小于等于 n 的相差为 k 的素数对. 输入格式 两个正整数n,k.1<=k<=n<=10000. 输出格式 所有小于等于n的素数对.每 ...

  4. H3C DHCP中继配置示例

  5. Spring Boot Admin-应用健康监控后台管理

    Spring Boot Admin 用于监控基于 Spring Boot 的应用,它是在 Spring Boot Actuator 的基础上提供简洁的可视化 WEB UI. 1. 什么是Spring ...

  6. Linux 内核中的数据类型

    在我们进入更高级主题之前, 我们需要停下来快速关注一下可移植性问题. 现代版本的 Linux 内核是 高度可移植的, 它正运行在很多不同体系上. 由于 Linux 内核的多平台特性, 打算做认真使用的 ...

  7. Visioi形状相关应用

    选择手柄为白点  按住shift的同时移动白点更为灵活 黄色的点就是控制手柄(只有一维图形有) 当调整形状出现绿色边的时候说明:这个时候这个形状的边等于了某个形状的长 铅笔工具可以移动控制点来更形状 ...

  8. TypeScript躬行记(7)——命名空间

    TypeScript中的命名空间可将那些具有内在联系的接口.类或对象等代码组织在一起,既能隔离作用域,也能避免命名冲突,并且使得代码结构清晰,更易追踪.在命名空间内部,所有实体部分默认都是私有的,需要 ...

  9. 【题解】BZOJ4548 小奇的糖果(树状数组)

    [题解]BZOJ4548 小奇的糖果(树状数组) 说在前面:我有个同学叫小奇,他有一个朋友叫达达,达达特爱地理和旅游,初中经常AK地理,好怀恋和他已经达达一起到当时初中附近许多楼盘的顶楼逛的时光... ...

  10. CompositePattern(组合模式)-----Java/.Net

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...