Description

  有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个操作,分为三种:

  操作 1 :把某个节点 x 的点权增加 a 。
  操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
  操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

Input

  第一行包含两个整数 N, M 。表示点数和操作数。

  接下来一行 N 个整数,表示树中节点的初始权值。
  接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。
  再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操
  作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。

Output

  对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

Sample Input

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

Sample Output

6
9
13

HINT

  对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不会超过 10^6 。

Source

  鸣谢bhiaibogf提供

Solution

  树链剖分,用线段树维护点权;对子树的修改就是区间修改,因为其dfs序是连续的

 #include <bits/stdc++.h>
using namespace std;
struct edge
{
int v, nxt;
}e[];
struct point
{
int val, siz, fa, son, dfn, top;
}p[];
struct seg
{
long long val, lazy;
}a[];
int fst[], ptot; void addedge(int i, int u, int v)
{
e[i] = (edge){v, fst[u]}, fst[u] = i;
} void DFS1(int u)
{
p[u].siz = ;
for(int i = fst[u]; i; i = e[i].nxt)
if(p[u].fa != e[i].v)
{
p[e[i].v].fa = u;
DFS1(e[i].v);
p[u].siz += p[e[i].v].siz;
if(p[e[i].v].siz > p[p[u].son].siz)
p[u].son = e[i].v;
}
} void DFS2(int u, int top)
{
p[u].dfn = ++ptot, p[u].top = top;
if(p[u].son) DFS2(p[u].son, top);
for(int i = fst[u]; i; i = e[i].nxt)
if(e[i].v != p[u].fa && e[i].v != p[u].son)
DFS2(e[i].v, e[i].v);
} void push_up(int o, int l, int r)
{
a[o].val = a[o << ].val + a[o << | ].val;
a[o].val += a[o].lazy * (r - l + );
} void push_down(int o, int l, int r)
{
int mid = (l + r) >> ;
if(l == r) return;
if(a[o].lazy)
{
a[o << ].lazy += a[o].lazy;
a[o << ].val += a[o].lazy * (mid - l + );
a[o << | ].lazy += a[o].lazy;
a[o << | ].val += a[o].lazy * (r - mid);
a[o].lazy = ;
}
} void update(int o, int l, int r, int ql, int qr, int val)
{
int mid = (l + r) >> ;
push_down(o, l, r);
if(ql <= l && r <= qr)
{
a[o].lazy += val;
a[o].val += (long long)val * (r - l + );
return;
}
if(ql <= mid) update(o << , l, mid, ql, qr, val);
if(mid < qr) update(o << | , mid + , r, ql, qr, val);
push_up(o, l, r);
} long long query(int o, int l, int r, int ql, int qr)
{
int mid = (l + r) >> ;
long long ans = ;
push_down(o, l, r);
if(ql <= l && r <= qr) return a[o].val;
if(ql <= mid) ans = query(o << , l, mid, ql, qr);
if(mid < qr) ans += query(o << | , mid + , r, ql, qr);
return ans;
} int main()
{
int n, m, u, v, op, x, val;
long long ans;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i)
scanf("%d", &p[i].val);
for(int i = ; i < n; ++i)
{
scanf("%d%d", &u, &v);
addedge(i << , u, v);
addedge(i << | , v, u);
}
DFS1(), DFS2(, );
for(int i = ; i <= n; ++i)
update(, , n, p[i].dfn, p[i].dfn, p[i].val);
while(m--)
{
scanf("%d", &op);
if(op == )
{
scanf("%d%d", &x, &val);
update(, , n, p[x].dfn, p[x].dfn, val);
}
else if(op == )
{
scanf("%d%d", &x, &val);
update(, , n, p[x].dfn, p[x].dfn + p[x].siz - , val);
}
else
{
scanf("%d", &x);
ans = ;
while(x)
{
ans += query(, , n, p[p[x].top].dfn, p[x].dfn);
x = p[p[x].top].fa;
}
printf("%lld\n", ans);
}
}
return ;
}

[BZOJ4034] [HAOI2015] T2 (树链剖分)的更多相关文章

  1. Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1841  Solved: 598[Submit][Status] ...

  2. BZOJ 4034: [HAOI2015]T2( 树链剖分 )

    树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...

  3. JZYZOJ1539[haoi2015]T2 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1539 在学校的OJ又写了一次,RE了好多次,原来haoi的时候这道题需要开栈+快读,裸数据结构30分,加上快读50分.o ...

  4. bzoj4034 树上操作 树链剖分+线段树

    题目传送门 题目大意: 有一棵点数为 N 的树,以点 1 为根,且树点有权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有 ...

  5. BZOJ 4034 [HAOI2015]树上操作(树链剖分)

    题目链接  BZOJ4034 这道题树链剖分其实就可以了. 单点更新没问题. 相当于更新 [f[x], f[x]]这个区间. f[x]表示树链剖分之后每个点的新的标号. 区间更新的话类似DFS序,求出 ...

  6. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  7. bzoj4034[HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6163  Solved: 2025[Submit][Stat ...

  8. BZOJ4034 [HAOI2015]树上操作 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...

  9. BZOJ 4034 [HAOI2015]T2(树链剖分)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4034 [题目大意] 有一棵点数为 N 的树,以点 1 为根,且树点有边权. 有 M 个 ...

随机推荐

  1. MySQL中四种常用存储引擎的介绍

    MySQL常用的四种引擎的介绍 (1):MyISAM存储引擎: 不支持事务.也不支持外键,优势是访问速度快,对事务完整性没有 要求或者以select,insert为主的应用基本上可以用这个引擎来创建表 ...

  2. netty学习资源收集

    Netty学习笔记 Netty In Actions CSDN专栏 一起学Netty-CSDN专栏 Netty In Action中文版

  3. 隱藏在素數規律中的Pi -- BZOJ1041解題報告

    退役狗在刷程書的過程中看到了一個有趣的視頻, 講解了一個有趣的問題. 在網上隨便搜索了一下居然還真的找到了一道以它爲背景的OI題目, BZOJ1041. 下面的內容會首先回顧一下視頻所討論的知識, 有 ...

  4. 消息队列(MQ)入门-activemq,代码级别

    第一种:activemq: 1.从官网下载apache-activemq-5.15.3-bin.zip并解压: 2.启动activemq, CMD--/bin/activemq start ,访问12 ...

  5. 用Putty通过SSH访问Linux服务器

    1,sudo apt-get install ssh 2,sudo service ssh restart 3,重启ssh成功后,就可以直接用Putty访问服务器.

  6. hdu1995 汉诺塔V

    可以直接把前K-1个罗盘全部忽略了,因为移动前K-1个罗盘不会影响第K个. 也就是相当于只移动剩下的n-k-1个罗盘,当只移动第k个罗盘时,f(k)=1;当要哟东第k个和第k+1个时,就必须先把第k个 ...

  7. Kubernetes 使用私服镜像

    非常感谢这些无私知识分享的同僚 重要参考:http://blog.csdn.net/u013812710/article/details/52766227 1.首先你得有个私库,这里我用的是阿里云私库 ...

  8. 使用IntelliJ IDEA 和 Maven创建Java Web项目

    1. Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和简单,所以这里也强调下,尽量使用此类工具进行项目构建, 它可以管理项目的整个生命周期. 可以通过其命令做所有相关的工 ...

  9. Centos小白学习

    目录 查看机器设备信息 有线网络设置(必须) 设置主机名(必须) 设置sudo用户,一般默认只有root可以使用(必须) yum更新源(必须) 安装完Centos后桌面宽度不能自适应 Centos安装 ...

  10. 【Unity3D】Unity3D开发《我的世界》之二、创建一个立方体

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/unity_minecraft_02.html 这一篇的内容比较简单,因为所有理论内容都在上一篇中讲到了.但有两点需 ...