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. scp 命令使用

    scp 是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且 scp传输是加密的.可能会稍微影响一下速度.当你服 ...

  2. if参数小结

    条件表达式 if [ -f  file ]    如果文件存在 if [ -d ...   ]    如果目录存在 if [ -s file  ]    如果文件存在且非空 if [ -r file  ...

  3. 相看系统中用户的信息 passwd, shadow

    用用户的信息都保存在 etc/passwd 和 etc/shadow 文件中,其中 shadow 保存的是经过加密码的 能过 cat etc/passwd 和 cat etc/shadow 来查看相关 ...

  4. jquery阻止事件的两种实现方式

    再阻止事件冒泡的方面,jquery有两种方式: 一种是 return false;另外一种是 e.stopPropagation() html代码 <form id="form1&qu ...

  5. 禁止选择文本和禁用右键 v1.0

    var zhonghao={ //绑定事件 myAddEvent: function(obj, sEvent, fn){if(obj.attachEvent){obj.attachEvent('on' ...

  6. 参数TFilterPredicate 类型说明

    类型名称:TFilterPredicate 类型定义: type TFilterPredicate = reference to function(const Path: string, const ...

  7. postgres 约束 多个条件 联合 约束

    ADD CONSTRAINT xxx CHECK ( (col1 = 0.0) = (col2 IS NOT NULL)); ## 相当于check (true = ture)

  8. 分享关于学习new BufferedWriter()方法时常遇到的一个无厘头的问题

    今天在学习IO的过程中,关于处理流BufferedWriter的使用时,遇到了一个很犯二但是又会让初学者经常没有避免的问题,百度后才发现有人和我一样二,这还是对java基础掌握得不牢固的原因啊. 首先 ...

  9. 关于textjs的tree带复选框的树

    通过查阅一些资料和自己之前了解到的一些相关知识,有时项目中需要用到.话不多说,先看一下效果图: 我写的这人员选择的树,主要是改写了TreePanel,如下代码: ExtendTreePanel.js ...

  10. XE5 开发android平台搭建

    转载自:http://www.cnblogs.com/hezihang/p/3319980.html Delphi XE5的Android开发平台搭建   Delphi XE5支持Android AR ...