这题已经确定了思路了,寻找区间,只是我在做的时候是通过记录各个节点的子结点的个数,而别人是直接通过dfs序来求,后者要好
#include <bits/stdc++.h>
using namespace std;
const int N = 50050;
vector <int> boss[N], employee[N];
int L[N * 4], R[N * 4];
int n, q, cnt;
int s[N * 4], e[N * 4];
int task[N * 4];
void init(){
for(int i = 0; i <= n; i ++){
boss[i]. clear();
employee[i]. clear();
}
}
void dfs(int u){
cnt ++;
L[u] = cnt;
for(int i = 0; i < boss[u]. size(); i ++){
int v = boss[u][i];
dfs(v);
}
R[u] = cnt;
}
void pushdown(int o, int num){
if(task[o] != -1){
task[o << 1] = task[o << 1 | 1] = task[o];
task[o] = -1;
}
}
void build(int l, int r, int o){
s[o] = l;
e[o] = r;
task[o] = -1;
if(l != r){
int m = (l + r) >> 1;
build(l, m, o << 1);
build(m + 1, r, o << 1 | 1);
}
}
void update(int t, int l, int r, int o){
if(s[o] == l && e[o] == r){
task[o] = t;
return ;
}
if(s[o] == e[o])
return ;
pushdown(o, e[o] - s[o] + 1);
int m = (s[o] + e[o]) >> 1;
if(r <= m)
update(t, l, r, o << 1);
else if(l > m)
update(t, l, r, o << 1 | 1);
else{
update(t, l, m, o << 1);
update(t, m + 1, r, o << 1 | 1);
}
}
int query(int x, int o){
if(s[o] == x && e[o] == x)
return task[o];
pushdown(o, e[o] - s[o] + 1);
int m = (s[o] + e[o]) >> 1;
if(x <= m)
return query(x, o << 1);
else
return query(x, o << 1 | 1);
}
int main(){
int T;
scanf("%d", &T);
for(int _ = 1; _ <= T; _ ++){
scanf("%d", &n);
init();
int u, v;
for(int i = 1; i < n; i ++){
scanf("%d %d", &u, &v);
boss[v]. push_back(u);
employee[u]. push_back(v);
}
cnt = 0;
for(int i = 1; i <= n; i ++)
if(employee[i]. size() == 0){
dfs(i);
break;
}
build(1, cnt, 1);
scanf("%d", &q);
printf("Case #%d:\n", _);
char op[5];
int x, y;
while(q --){
scanf("%s", op);
if(op[0] == 'C'){
scanf("%d", &x);
printf("%d\n", query(L[x], 1));
}
else if(op[0] == 'T'){
scanf("%d %d", &x, &y);
update(y, L[x], R[x], 1);
}
}
}
return 0;
}