codeforces 343 D Water Tree

题目
div1的D题,树链剖分模板题
初始状态:树上全是0
操作1:把u的孩子全变成1
操作2:把u的祖先全变成0
操作3:查询u结点的值

树链剖分部分:树上区间修改,子树修改
线段树部分:区间修改,单点查询

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 5e5 + 5;
struct Tree{
	int l, r, val;
	int lazy;
	#define l(p) tree[p].l
	#define r(p) tree[p].r
	#define lazy(p) tree[p].lazy
	#define val(p) tree[p].val
	#define lson(p) p << 1
	#define rson(p) p << 1 | 1
}tree[N << 2];
void pushdown(int p){
	if(lazy(p) != -1){
		lazy(lson(p)) = lazy(rson(p)) = lazy(p);
		val(lson(p)) = val(rson(p)) = lazy(p);
		lazy(p) = -1;
	}
}
void build(int p, int l, int r){
	l(p) = l, r(p) = r, lazy(p) = -1, val(p) = 0;
	if(l == r){
		return;
	}
	int mid = (l + r) >> 1;
	build(lson(p), l, mid);
	build(rson(p), mid + 1, r);
}
void Change(int p, int l, int r, int val){
	if(l <= l(p) && r(p) <= r){
		lazy(p) = val(p) = val;
		return;
	}
	pushdown(p);
	int mid = (l(p) + r(p)) >> 1;
	if(l <= mid)Change(lson(p), l, r, val);
	if(r > mid)Change(rson(p), l, r, val);
}
int Query(int p, int x){
	if(l(p) == r(p)){
		return val(p);
	}
	pushdown(p);
	int mid = (l(p) + r(p)) >> 1;
	if(x <= mid)return Query(lson(p), x);
	else return Query(rson(p), x);
}
struct Edge{
	int to, next;
}e[N << 1];
int head[N], tot;
void add(int u, int v){
	e[++tot].to = v;
	e[tot].next = head[u];
	head[u] = tot;
}
int fa[N], depth[N], son[N], siz[N];
void dfs(int u, int fath){
	fa[u] = fath, depth[u] = depth[fath] + 1;
	siz[u] = 1;
	for(int i = head[u]; i; i = e[i].next){
		int v = e[i].to;
		if(v == fath)continue;
		dfs(v, u);
		siz[u] += siz[v];
		if(siz[v] > siz[son[u]])son[u] = v;
	}
}
int dfn[N], top[N], cnt;
void dfs2(int u, int rt){
	dfn[u] = ++cnt;
	top[u] = rt;
	if(son[u]) dfs2(son[u], rt);
	for(int i = head[u]; i; i = e[i].next){
		int v = e[i].to;
		if(v != fa[u] && v != son[u])dfs2(v, v);
	}
} 
void ModifyOnTree(int u, int v, int val){
	while(top[u] != top[v]){
		if(depth[top[u]] < depth[top[v]])swap(u, v);
		Change(1, dfn[top[u]], dfn[u], val);
		u = fa[top[u]];
	}
	if(depth[u] > depth[v])swap(u, v);
	Change(1, dfn[u], dfn[v], val);
}
void ModifyOnSon(int u, int val){
	Change(1, dfn[u], dfn[u] + siz[u] - 1, val);
}
int QueryOnTree(int u){
	return Query(1, dfn[u]);
}
int main(){
	int n, m;
	scanf("%d", &n);
	for(int i = 1; i < n; i++){
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v); add(v, u);
	}
	dfs(1, 0); dfs2(1, 1);
	build(1, 1, n);
	scanf("%d", &m);
	for(int i = 1; i <= m; i++){
		int op, v;
		scanf("%d%d", &op, &v);
		if(op == 1)ModifyOnSon(v, 1);
		if(op == 2)ModifyOnTree(1, v, 0);
		if(op == 3)printf("%d
", QueryOnTree(v));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Emcikem/p/12845027.html