题目链接

loj#2054. 「TJOI / HEOI2016」树

题解

每次标记覆盖整棵字数,子树维护对于标记深度取max

dfs序+线段树维护一下

代码

#include<cstdio>
#include<algorithm> inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9')c = getchar();
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
int n,m;
const int maxn = 200007;
struct node {
int v,next;
} edge[maxn << 1];
int head[maxn],num = 0;
inline void add_edge(int u,int v) {
edge[++ num].v = v; edge[num].next = head[u];head[u] = num;
edge[++ num].v = u; edge[num].next = head[v];head[v] = num;
} int dfn[maxn],low[maxn],dep[maxn];
struct seg {
#define ls x << 1,l,mid
#define rs x << 1 | 1,mid + 1,r
int t[maxn << 1];
void build(int x,int l,int r) {
if(l == r) { t[x] = 1; return; }
int mid = l + r >> 1;
build(ls);
build(rs);
}
inline void cover(int x,int k) {
if(!t[x]) t[x] = k;
else t[x] = dep[t[x]] < dep[k] ? k : t[x];
}
inline void pushdown(int x) {
cover(x << 1,t[x]);
cover(x << 1 | 1,t[x]);
t[x] = 0;
}
int query(int x,int l,int r,int k) {
if(l == r) return t[x];
if(t[x]) pushdown(x);
int mid = l + r >> 1;
if(k <= mid) return query(ls,k);
else return query(rs,k);
}
void modify(int x,int l,int r,int L,int R,int k) {
if(L <= l && R >= r) {
cover(x,k); return ;
}
if(t[x]) pushdown(x);
int mid = l + r >> 1;
if(L <= mid) modify(ls,L,R,k);
if(R > mid ) modify(rs,L,R,k);
}
}t; int idx = 0;
void dfs(int x,int fa = 0) {
dfn[x] =++ idx;
dep[x] = dep[fa] + 1;
for(int i = head[x];i;i = edge[i].next)
if(edge[i].v != fa) dfs(edge[i].v,x);
low[x] = idx;
}
int main() {
n = read(); m = read();
int cnt = 1;
for(int i = 1;i < n;++ i) {
add_edge(read(),read());
}
dfs(1);
t.build(1,1,n);
char ty[3];
for(int x,i = 1;i <= m;i += 1) {
scanf("%s",ty + 1);
if(ty[1] == 'Q') {
printf("%d\n",t.query(1,1,n,dfn[read()]));
} else {
x = read();
t.modify(1,1,n,dfn[x],low[x],x);
}
}
return 0;
}
04-30 11:49