4034: [HAOI2015]T2

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1536  Solved: 508
[Submit][Status][Discuss]

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

【思路】

  树链剖分,线段树

  线段树:区间和,区间修改add

【代码】

 #include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long LL;
const int N = +; struct Node { LL sum,addv;
}T[N<<]; int n,q,z,c[N];
vector<int> g[N];
//INIT
int top[N],son[N],dep[N],fa[N],siz[N],w[N],mxw[N];
void dfs1(int u) {
son[u]=; siz[u]=;
for(int i=;i<g[u].size();i++) {
int v=g[u][i];
if(v!=fa[u]) {
fa[v]=u , dep[v]=dep[u]+;
dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int tp) {
top[u]=tp; w[u]=mxw[u]=++z;
if(son[u])
dfs2(son[u],tp),mxw[u]=max(mxw[u],mxw[son[u]]);
for(int i=;i<g[u].size();i++) {
int v=g[u][i];
if(v!=fa[u] && v!=son[u])
dfs2(v,v),mxw[u]=max(mxw[u],mxw[v]);
}
}
//SEGMENT TREE
void pushdown(int u,int l,int r) {
if(T[u].addv && l<r) {
int lc=u<<,rc=lc|,M=(l+r)>>;
T[lc].sum+=T[u].addv*(M-l+);
T[rc].sum+=T[u].addv*(r-M);
T[lc].addv+=T[u].addv,T[rc].addv+=T[u].addv;
T[u].addv=;
}
}
void update(int u,int L,int R,int l,int r,int x) {
pushdown(u,L,R);
if(l<=L && R<=r)
T[u].addv+=x , T[u].sum+=x*(R-L+);
else {
int M=(L+R)>>,lc=u<<,rc=lc|;
if(l<=M) update(lc,L,M,l,r,x);
if(M<r) update(rc,M+,R,l,r,x);
T[u].sum=T[lc].sum+T[rc].sum;
}
}
LL query(int u,int L,int R,int l,int r) {
pushdown(u,L,R);
if(l<=L && R<=r) return T[u].sum;
else {
int M=(L+R)>>; LL ans=;
if(l<=M) ans+=query(u<<,L,M,l,r);
if(M<r) ans+=query(u<<|,M+,R,l,r);
return ans;
}
}
//Ê÷Á´ÆÊ·Ö
LL query(int u) {
LL sum=;
while(top[u]!=) {
sum+=query(,,z,w[top[u]],w[u]);
u=fa[top[u]];
}
sum+=query(,,z,,w[u]);
return sum;
} void read(int& x) {
char c=getchar(); int f=; x=;
while(!isdigit(c)) {if(c=='-')f=-;c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
x*=f;
}
int main() {
//freopen("in.in","r",stdin);
//freopen("out.in","w",stdout);
read(n),read(q);
FOR(i,,n) read(c[i]);
int u,v,x,op,y;
FOR(i,,n-) {
read(u),read(v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(),dfs2(,);
FOR(i,,n) update(,,z,w[i],w[i],c[i]);
while(q--) {
read(op),read(x);
if(op==)
read(y),update(,,z,w[x],w[x],y);
else if(op==)
read(y),update(,,z,w[x],mxw[x],y);
else
printf("%lld\n",query(x));
}
return ;
}

bzoj 4034 [HAOI2015] T2(树链剖分,线段树)的更多相关文章

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

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

  2. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  3. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  4. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

  5. bzoj 2157: 旅游【树链剖分+线段树】

    裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...

  6. BZOJ 3589 动态树 (树链剖分+线段树)

    前言 众所周知,90%90\%90%的题目与解法毫无关系. 题意 有一棵有根树,两种操作.一种是子树内每一个点的权值加上一个同一个数,另一种是查询多条路径的并的点权之和. 分析 很容易看出是树链剖分+ ...

  7. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  8. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

  9. [HDU3710] Battle Over Cities [树链剖分+线段树+并查集+kruskal+思维]

    题面 一句话题意: 给定一张 N 个点, M 条边的无向连通图, 每条边上有边权 w . 求删去任意一个点后的最小生成树的边权之和. 思路 首先肯定要$kruskal$一下 考虑$MST$里面去掉一个 ...

  10. [luogu3676] 小清新数据结构题 [树链剖分+线段树]

    题面 传送门 思路 本来以为这道题可以LCT维护子树信息直接做的,后来发现这样会因为splay形态改变影响子树权值平方和,是splay本身的局限性导致的 所以只能另辟蹊径 首先,我们考虑询问点都在1的 ...

随机推荐

  1. ASP.NET缓存 Cache

    缓存介绍 如果每次进入页面的时候都查询数据库生成页面内容的话,如果访问量非常大,则网站性能会非常差,而如果只有第一次访问的时候才查询数据库生成页面内容,以后都直接输出内容,则能提高系统性能,这样无论多 ...

  2. python 自动化之路 day 03

    内容目录: 1. 字典 2. 集合 3. 文件处理 4. 字符编码   1. 字典操作 字典一种key - value 的数据类型,使用就像我们上学用的字典,通过笔划.字母来查对应页的详细内容. 语法 ...

  3. ubuntu 12.04 mysql转移目录后 无法 启动

    http://www.boyunjian.com/do/article/snapshot.do?uid=com.iteye.xgbjmxn%2Fblog%2F1208086(转,)     我是用ap ...

  4. centos VM 识别U盘

    在VM设置选项中,选择 USB Controller 选项,设置相关参数即可

  5. MySQL的基本

    MySQL的基本语法 left JOIN 左表匹配右表 有没有内容全部匹配 SELECT Persons.LastName, Orders.OrderNo FROM Persons INNER JOI ...

  6. 上传文件格式控制的困惑(application/octet-stream 限制不了BAT等格式上传)问题解决

    允许上传类型部分代码 $uptypes=array(  //上传文件类型列表 'image/gif', 'image/jpg', 'image/jpeg', 'image/pjpeg', 'image ...

  7. 基于ARM-LINUX的温度传感器驱动(DS18B20) .

    DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等.主要根据应用场合的不同而改变其外观.封装 ...

  8. centos 6.3 64位安装php5.5及配置tengine

    PHP 用到的工具包: yum install gd-devel libjpeg-devel libpng-devel freetype-devel libxml2-devel curl-devel ...

  9. Java 单链表的倒置

    在面试,笔试的过程中经常会遇到面试官问这种问题,实现单链表的倒置方法.现在对单链表的倒置犯法做个记录,方便自己以后查看. 单链表的定义: public class Node { int v; Node ...

  10. ul动态增加li

    --> aaa bbb <%@ page language="java" import="java.util.*" pageEncoding=&qu ...