题目链接:hdu 3974
大意:给你一棵树,当你在某个结点修改地时候,那么以这个结点为根地子树地所有结点都会做一样的修改,我们可以把这个树转化为区间问题,按照dfs的方式去遍历这棵树,然后入栈的序列即这些结点转化为区间时在区间中的序号,因此每个结点所代表的子树相当于一段区间,我们要记录每个结点所对应的区间起点和区间终点。看代码即可理解!
代码:
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
#define maxn 50000+5
vector<int> vv[maxn];
int startt[maxn], endd[maxn];
int tree[maxn<<2];
int col[maxn<<2];
int cnt;
void turn_tree_line(int u)
{
cnt++;
startt[u] = cnt;
for(int i = 0; i < vv[u].size(); i++){
turn_tree_line(vv[u][i]);
}
endd[u] = cnt;
}
void build(int left, int right, int rt)
{
tree[rt] = -1;
col[rt] = 0;
if(left == right) return ;
int mid = (left + right)>>1;
build(left, mid, rt<<1);
build(mid + 1, right, (rt<<1)|1);
}
void pushDown(int rt)
{
if(col[rt]){
tree[rt<<1] = tree[(rt<<1)|1] = tree[rt];
col[rt<<1] = col[(rt<<1)|1] = col[rt];
col[rt] = 0;
}
}
int query(int pos, int left, int right, int rt)
{
if(left == right)
return tree[rt];
int mid = (left + right)>>1;
pushDown(rt);
if(pos <= mid) return query(pos, left, mid, rt<<1);
else if(pos > mid) return query(pos, mid + 1, right, (rt<<1)|1);
}
void upDate(int l, int r, int c, int left, int right, int rt)
{
if(l <= left && right <= r){
tree[rt] = c;
col[rt] = 1;
return ;
}
pushDown(rt);
int mid = (left + right)>>1;
if(l <= mid) upDate(l, r, c, left, mid, rt<<1);
if(r > mid) upDate(l, r, c, mid + 1, right, (rt<<1)|1);
}
int main()
{
int t, n, m, a, b, cases = 1;
scanf("%d", &t);
while(t--){
printf("Case #%d:\n", cases++);
for(int i = 0; i < maxn; i++){
vv[i].clear();
}
cnt = 0;
int dd[maxn];
memset(dd, 0, sizeof(dd));
scanf("%d", &n);
build(1, n, 1);
for(int i = 0; i < n - 1; i++){
scanf("%d%d", &a, &b);
vv[b].push_back(a);
dd[a] = 1;
}
int u;
for(int i = 1; i <= n; i++)
if(dd[i] == 0) u = i;
turn_tree_line(u);
scanf("%d", &m);
char ch[10]; int d, e;
for(int i = 0; i < m; i++){
scanf("%s", ch);
if(ch[0] == 'C'){
scanf("%d", &d);
printf("%d\n", query(startt[d], 1, n, 1));
}
else if(ch[0] == 'T'){
scanf("%d%d", &d, &e);
upDate(startt[d], endd[d], e, 1, n, 1);
}
}
}
return 0;
}
/*
100
15
2 1
9 1
3 2
6 2
4 3
5 3
7 6
8 6
11 10
10 9
12 10
14 13
15 13
13 9
*/