题目
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;
}