bzoj4034 (树链剖分+线段树)
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 (树链剖分+线段树)的更多相关文章
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- 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 ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
随机推荐
- Thread 总结
进程:是一个正在执行的程序 每一个进程执行都有一个执行顺序.该顺序是一个执行路劲,后者叫一个控制单元. 线程:就是进程中的一个独立控制单元. 线程在控制着进程的执行 一个进程中至少有个一个线程 Jav ...
- IE9中Media queries在iframe无效的解决方法
在css中有5个media querie @media screen and(min-width:0px)and(max-width:319px){ body {background-color:re ...
- PDF 补丁丁 0.4.1.839 测试版发布:调整页面留白
新的测试版的补丁功能实现了调节页面留白的功能(之前的820版尚未实现该功能),页面合并功能支持从资源管理器拖放文件或目录到列表,还修正了一些问题. 欢迎下载测试.
- BPMX3模拟登录
实现功能只需要输入一个帐号即可登录系统. 需要实现上面的功能需要: 1.编辑imitate.jsp页面 <%@page import="com.hotent.core.util.Con ...
- 作用域闭包、预解释和this关键字综合题目
var number = 2; var obj = {number : 5, fn1 : ( function() { this.number *= 2; number=number*2; var n ...
- 网页优化URI(http URI scheme与data URI scheme)
网页优化的一大首要任务是减少HTTP 请求 (http request) 的次数,例如通过合并多个JS文件,合并CSS样式文件.除此之外,还有一个data URL 的密技,让我们直接把图像的内容崁入网 ...
- 互斥锁pthread_mutex_t的使用(转载)
1. 互斥锁创建 有两种方法创建互斥锁,静态方式和动态方式.POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥锁,方法如下: pthread_mut ...
- C char** 的一点儿理解
理解是就是char** 相当于字符串数组,我以往纠结于该用 **arr还是*arr还是 (*arr),还是(**arr): 对于**arr而言:*arr代表数组的最开头,也就是第一个字串的内容.**a ...
- C++定义构造函数必须使用初始化列表的场合
明其理,而知其然也. 先给理论.1. 初始化 != 赋值. a.初始化代表为变量分配内存. 变量在其定义处被编译器初始化(编译时). 在函数中, 函数参数初始化发生在函数调用时(运行时). b.赋值代 ...
- CPU是怎么制造的
大概的过程就是,先选一堆好沙子(纯净的沙子),初步加工一般在沿海,然而都是初加工,因为技术不行,所以一般用比较污染环境的方法加工大99.9%纯度的硅,然后低价卖给国外企业,用高精尖技术加工到99.99 ...