Problem T2 (bzoj4034 HAOI2015)

题目大意

  给定一颗树,1为根节点,要求支持三种操作。

  操作 1 :把某个节点 x 的点权增加 a 。

  操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。  

  操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

解题分析

  练手题。树链剖分+线段树。

参考程序

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; #define V 100008
#define E 200008
#define lson l,m,rt << 1
#define rson m+1,r,rt << 1 | 1
#define LL long long struct line{
int u,v,w,nt;
}eg[E];
int sum,lt[V]; void adt(int u,int v){
eg[++sum].u=u; eg[sum].v=v; eg[sum].nt=lt[u]; lt[u]=sum;
}
void add(int u,int v){
adt(u,v); adt(v,u);
} int size[V],fa[V],dep[V],son[V],w[V],top[V],rk[V];
int n,m,a[V],cnt; void dfs_1(int u){
size[u]=; dep[u]=dep[fa[u]]+; son[u]=;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u]) continue;
fa[v]=u;
dfs_1(v);
size[u]+=size[v];
if (size[v]>size[son[u]]) son[u]=v;
}
} void dfs_2(int u,int tp){
top[u]=tp; w[u]=++cnt; rk[cnt]=u;
if (son[u]) dfs_2(son[u],tp);
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u] || v==son[u]) continue;
dfs_2(v,v);
}
} struct segment_tree{
LL sum[V << ],lazy[V << ];
void pushup(int rt){
sum[rt]=sum[rt<<]+sum[rt<<|];
}
void pushdown(int rt,int m){
if (lazy[rt]){
lazy[rt<<]+=lazy[rt];
lazy[rt<<|]+=lazy[rt];
sum[rt<<]+=lazy[rt] * (m-m/);
sum[rt<<|]+=lazy[rt] * (m/);
lazy[rt]=;
}
}
void build(int l,int r,int rt){
lazy[rt]=;
if (l==r){
sum[rt]=a[rk[l]];
return;
}
int m=(l+r)/;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt){
if (L<=l && r<=R){
lazy[rt]+=val;
sum[rt]+=1ll*(r-l+)*val;
return;
}
pushdown(rt,r-l+);
int m=(l+r)/;
if (L <= m) update(L,R,val,lson);
if (m < R) update(L,R,val,rson);
pushup(rt);
}
LL query(int L,int R,int l,int r,int rt){
if (L<=l && r<=R){
return sum[rt];
}
pushdown(rt,r-l+);
int m=(l+r)/;
LL res=;
if (L <= m) res+=query(L,R,lson);
if (m < R) res+=query(L,R,rson);
return res;
}
}T; void change(int x,int y){
LL res=;
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
res+=T.query(w[top[x]],w[x],,n,);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
res+=T.query(w[x],w[y],,n,);
printf("%lld\n",res );
} int main(){
memset(lt,,sizeof(lt)); sum=;
scanf("%d %d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<n;i++){
int u,v;
scanf("%d %d",&u,&v);
add(u,v);
}
dfs_1();
dfs_2(,);
T.build(,n,);
while (m--){
int x,y,z;
scanf("%d",&x);
if (x==){
scanf("%d %d",&y,&z);
T.update(w[y],w[y],z,,n,);
}
if (x==){
scanf("%d %d",&y,&z);
T.update(w[y],w[y]+size[y]-,z,,n,);
}
if (x==){
scanf("%d",&y);
change(,y);
}
}
}

  

bzoj4034 (树链剖分+线段树)的更多相关文章

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

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

  2. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

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

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

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

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  5. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  6. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

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

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

  8. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

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

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

随机推荐

  1. Roman to Integer [LeetCode]

    Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 t ...

  2. 79. 212. Word Search *HARD* -- 字符矩阵中查找单词

    79. Word Search Given a 2D board and a word, find if the word exists in the grid. The word can be co ...

  3. groovy基础

    字符串字面值 def age=25 log.info 'My age is ${age}' log.info "my age is \${age}" log.info " ...

  4. hadoop主节点(NameNode)备份策略以及恢复方法

    link:http://jiajun.iteye.com/blog/809125 一.dits和fsimage 首先要提到两个文件edits和fsimage,下面来说说他们是做什么的. 集群中的名称节 ...

  5. BZOJ3942 [Usaco2015 Feb]Censoring

    维护一个栈...如果栈顶出现了要被删除的字符串就全删掉就好了,判断的话...kmp就行了 /****************************************************** ...

  6. 常用的js函数

    function $(){ return document.getElementById(arguments[0])}; /** * 得到上一个元素 * @param {Object} elem */ ...

  7. http://ecgui.com/?hg=0&nr=0

    eCGUI- 微型嵌入式GUI体积小巧 大小在 100KB~180KB! 特性: 多窗口支持| 完全中文输入/显示| 多数常用GUI控件| 99.9% ANSI C 编写| 已成功移植 DOS,Lin ...

  8. [Jquery]瀑布流

    $(window).load(function(e){    waterfall();    var dataInt={'data':[{'src':'1.jpg'},{'src':'2.jpg'}, ...

  9. TCP/IP 某些最常见的错误原因码 (errno)列表

    对于在基于 UNIX 的环境中的 TCP/IP 用户,下表列出了某些最常见的错误原因码 (errno).它不是完整的错误列表.可以在文件 /usr/include/sys/errno.h 中找到 Er ...

  10. ROS主题发布订阅

    节点是一个可执行程序,它连接到了ROS的网络系统中.我们将会创建一个发布者,也就是说话者节点,它将会持续的广播一个信息. 改变目录到之前所建立的那个包下: cd ~/catkin_ws/src/beg ...