洛谷P3178[HAOI]2015 树上操作
树剖裸题,这个题更可以深刻的理解树剖中把树上的节点转换为区间的思想。
要注意在区间上连续的节点,一定是在一棵子树中。
#include <bits/stdc++.h>
#define int long long
#define ls left, mid, root << 1
#define rs mid + 1, right, root << 1 | 1
#define N 600100
using namespace std;
int n, m, rot, mod, tot, cnt;
int data[N], id[N], dep[N], size[N], lin[N], ans[N * 8], lazy[N * 8], dp[N], fa[N], top[N], son[N];
struct edg {
	int to, nex;
} e[N];
inline void add(int f, int t)
{
	e[++cnt].to = t;
	e[cnt].nex = lin[f];
	lin[f] = cnt;
}
inline void pushup(int root)
{
 	ans[root] = (ans[root << 1] + ans[root << 1 | 1]);
}
inline void pushdown(int root, int left, int right)
{
  	int mid = (left + right) >> 1;
   	if (lazy[root])
   	{
		ans[root << 1] += (mid - left + 1) * lazy[root];
		ans[root << 1];
		ans[root << 1 | 1] += (right - mid) * lazy[root];
		ans[root << 1 | 1];
		lazy[root << 1] += lazy[root];
		lazy[root << 1 | 1] += lazy[root];
		lazy[root] = 0;
	}
}
void build(int left, int right, int root)
{
	if (left == right)
	{
		ans[root] = dp[left], ans[root];
		return;
	}
	int mid = (left + right) >> 1;
	build(ls), build(rs);
	pushup(root);
}
inline void update(int left, int right, int root, int add, int ql, int qr)
{
	if (left >= ql && right <= qr)
	{
		ans[root] += (right - left + 1) * add;
		lazy[root] += add;
		ans[root];
		return;
	}
	int mid = (left + right) >> 1;
	pushdown(root, left, right);//线段树的pushdown操作是为了弥补之前没向下传递标记的坑。
	if (ql <= mid)
		update(ls, add, ql, qr);
	if (qr > mid)
		update(rs, add, ql, qr);
	pushup(root);
}
inline int query(int left, int right, int root, int ql, int qr)
{
	int res = 0;
	if (left >= ql && right <= qr)
		return ans[root];
	int mid = (left + right) >> 1;
	pushdown(root, left, right);
	if (ql <= mid)
		res = ( res + query(ls, ql, qr) );
	if (qr > mid)
		res = res + query(rs, ql, qr) ;
	return res;
}
void dfs1(int now, int f, int de)
{
	fa[now] = f, dep[now] = de, size[now] = 1;
	int maxsize = -1;
	for (int i = lin[now]; i; i = e[i].nex)
	{
		if (e[i].to == f) continue;
		dfs1(e[i].to, now, de + 1);
		size[now] += size[e[i].to];
		if (size[e[i].to] > maxsize)
		{
			maxsize = size[e[i].to];
			son[now] = e[i].to;
		}
	}
}
void ulca(int x, int y, int z)
{
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		update(1, n, 1, z, id[top[x]], id[x]);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	update(1, n, 1, z, id[x], id[y]);
}
int qlca(int x, int y)
{
	int res = 0;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		res = ( res + query(1, n, 1, id[top[x]], id[x]) );
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	res = ( res + query(1, n, 1, id[x], id[y]) );
	return res;
}
void upd(int x, int y)
{
	update(1, n, 1, y, id[x], id[x] + size[x] - 1);
}
int que(int x)
{
	return query(1, n, 1, id[x], id[x] + size[x] - 1);
}
void dfs2(int now, int t)
{
	top[now] = t;
	dp[++tot] = data[now];
	id[now] = tot;
	if (!son[now])
		return;
	dfs2(son[now], t);
	for (int i = lin[now]; i; i = e[i].nex)
	{
		int to = e[i].to;
		if (to != fa[now] && to != son[now])
			dfs2(to, to);
	}
}
signed main()
{
	scanf("%lld%lld", &n, &m);
	rot = 1;
	for (int i = 1; i <= n; i++)
			scanf("%lld", &data[i]);
	for (int i = 1; i < n; i++)
	{
		int a, b;
		scanf("%lld%lld", &a, &b);
		add(a, b);
		add(b, a);
	}
	dfs1(rot, 0, 1);
	dfs2(rot, rot);
	build(1, n, 1);
	for (int i = 1; i <= m; i++)
	{
		int flag;
		scanf("%lld", &flag);
		if (flag == 1)
		{
			int x, a;
			scanf("%lld%lld", &x, &a);
			update(1, n, 1, a, id[x], id[x]);
		}
		if (flag == 2)
		{
			int x, a;
			scanf("%lld%lld", &x, &a);
			update(1, n, 1, a, id[x],  id[x] + size[x] - 1);
		}
		if (flag == 3)
		{
			int a;
			scanf("%lld", &a);
			printf("%lld\n", qlca(1, a));//不能写成id[1],id[a]因为id子树之间是连续的,所以a到1之间并不是连续边号。
		}
	}
	return 0;
}
/*
5 5 2 24
7 3 7 8 0
1 2
1 5
3 1
4 1
3 4 2
3 2 2
4 5
1 5 1 3
2 1 3
*/
												
											洛谷P3178[HAOI]2015 树上操作的更多相关文章
- cogs 1963. [HAOI 2015] 树上操作 树链剖分+线段树
		
1963. [HAOI 2015] 树上操作 ★★★☆ 输入文件:haoi2015_t2.in 输出文件:haoi2015_t2.out 简单对比时间限制:1 s 内存限制:256 M ...
 - [bzoj 4034][HAOI 2015]树上操作
		
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
 - 洛谷 P4665 [BalticOI 2015]Network
		
洛谷 P4665 [BalticOI 2015]Network 你有一棵 $ n $ 个节点的树,你可以在树上加一些边,使这棵树变成一张无重边.自环的图,且删掉任意一条边它仍然联通.求最少要加多少条边 ...
 - 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
		
P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...
 - 洛谷 P3178 BZOJ 4034 [HAOI2015]树上操作
		
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
 - 洛谷P1273 有线电视网 (树上分组背包)
		
洛谷P1273 有线电视网 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节 ...
 - 洛谷P3177||bzoj4033 [HAOI2015]树上染色
		
洛谷P3177 bzoj4033 根本不会做... 上网查了题解,发现只要在状态定义的时候就考虑每一条边全局的贡献就好了? 考虑边的贡献和修改状态定义我都想到了,然而并不能想到要结合起来 ans[i] ...
 - bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作
		
2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ...
 - 洛谷P3178 [HAOI2015]树上操作 题解 树链剖分+线段树
		
题目链接:https://www.luogu.org/problem/P3178 这道题目是一道树链剖分的模板题. 但是在解决这道问题的同事刷新了我的两个认识: 第一个认识是:树链剖分不光可以处理链, ...
 
随机推荐
- golang--获取进程ID(windows)
			
package main import ( "fmt" "strconv" "syscall" "unsafe" ) t ...
 - Java JDK1.8源码学习之路  1  Object
			
写在最前 对于一个合格的后端程序员来说,现行的流行框架早已经能胜任基本的企业开发,Springboot 任何的框架都把重复的工作更佳简单/优化的解决掉,但是完全陷入在这样的温水里面, 好比温水煮青蛙, ...
 - Linux用户组笔记整理
			
一.Linux用户组概念 Linux用户组(group)就是具有相同操作权限范围的Linux用户管理起来: 比如有时我们要让同一类用户具有相同的权限,比如查看.修改某一文件或执行某个命令, 这时我们需 ...
 - easyui-datagrid 假分页
			
假分页就是将数据一下全查出来,利用前端来把所有数据进行分页
 - ActiveX的AssemblyInof.cs文件 IObjectSafety  接口
			
ActiveX的AssemblyInof.cs文件 IObjectSafety 接口 [Guid("D4176A17-2A33-4903-8F37-9EBDD7CAFFD3"), ...
 - android 常用库的地址--dialog,recycler
			
android 弹出框 https://github.com/li-xiaojun/XPopup android RecyclerViewAdapter https://github ...
 - 用less查看日志文件
			
一般程序部署在Linux环境,查看日志时,一般用less满足大部分的需求. 列举.记录最常用的场景,代码以Tomcat日志文件catalna.out为例. 1. > 直接查看文件 less ca ...
 - 你再也不用使用 Redux、Mobx、Flux 等状态管理了
			
Unstated Next readme 的中文翻译 前言 这个库的作者希望使用 React 内置 API ,直接实现状态管理的功能.看完这个库的说明后,没有想到代码可以这个玩.短短几行代码,仅仅使用 ...
 - 在safari下input的placeholder设置行高失效
			
在项目中遇到input的placeholder在safari下设置行高失效的问题,亲测 input{ width:250px; height:30px; line-height:30px; font- ...
 - layui 单选框、复选框、下拉菜单 不显示问题 记录
			
1. 如果是 ajax嵌套了 页面, 请确保 只有最外层的页面引入了 layui.css 和 layui.js 内层页面 切记不要再次引入 2. layui.use(['form', 'upload ...