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. Wunder Fund Round 2016 (Div. 1 + Div. 2 combined)

    现在水平真的不够.只能够做做水题 A. Slime Combining 题意:就是给n个1给你.两个相同的数可以合并成一个数,比如说有两个相同的v,合并后的值就是v+1 思路:直接模拟栈 #inclu ...

  2. Python--day39--进程池的回调函数callback

    运行结果:

  3. 2019-10-10-优雅调试-REST-API-的工具

    title author date CreateTime categories 优雅调试 REST API 的工具 lindexi 2019-10-10 20:9:33 +0800 2019-10-1 ...

  4. 通过作用域链解析js函数一些难以理解的的作用域问题

    基本原理 js函数在执行时,系统会创建一个隐式的属性scope,scope中存储的是函数的作用域链. 通过对这个scope的分析,就能解释JavaScript中许多难以理解的问题: 例1: funct ...

  5. linux 选择 ioctl 命令

    在为 ioctl 编写代码之前, 你需要选择对应命令的数字. 许多程序员的第一个本能的反 应是选择一组小数从0或1 开始, 并且从此开始向上. 但是, 有充分的理由不这样做. ioctl 命令数字应当 ...

  6. sparksql 练习题两道

    第一题:select '{"id":1,"name":{"url":"http://xxx/yyy/zz/test.js" ...

  7. 一个APP从启动到主页面显示经历了哪些过程?

    ①点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求: ②system_server进程接收到请求后,向zygote进程 ...

  8. 记一次手工清除挖矿病毒WannaMine V4.0的经历

    [作者:byeyear    邮箱:byeyear@hotmail.com    转载请注明] 前两天公司信息安全处通知我的计算机存在永恒之蓝漏洞并已被病毒感染,使用多方杀软及专杀工具均无法有效清除, ...

  9. 专业版12.0试用,打开演示账套,提示&ldquo;列名FPlatver无效&rdquo;

    你好,我代表研发来说明一下这个问题:一.产生的原因:由于KIS产品今年陆续都增加了应用平台,前期平台兼容性还有些问题,如果一台电脑有多个不同版本的平台,就会产生冲突,因此报错.1.可能您的机器装了多个 ...

  10. ELK学习实验008:Kibana的介绍

    一 简介 Kiana是一款开源的数据分析和可视化平台,它是 Elastic Stack成员之一,设计用于和 Elasticsearch协作.您可以使用 Kiana对 Elasticsearch索引中的 ...