1 /*
2 hdu3974
3 dfs序建树,然后区间修改查询;
4 */
5 #include<iostream>
6 #include<cstdio>
7 #include<cstring>
8 #include<algorithm>
9 #define MAX_N 50005
10 using namespace std;
11
12 int N,M;
13 struct Node
14 {
15 int to,next;
16 }edge[MAX_N];
17 struct TREE
18 {//val记录的是区间;
19 int l,r,val,lazy;
20 }tr[MAX_N*4];
21 int head[MAX_N],cnt,tot;
22 int Start[MAX_N],End[MAX_N];
23
24 void Addedge(int u,int v)//链式前向星存图;
25 {
26 //tot是边的编号;
27 edge[tot].to=u;//以v为起点的边;终点是u;
28 edge[tot].next=head[v];//这条边的下一条边是几号边,依然是v为起点的边;
29 head[v]=tot++;//更新v为起点的边的入口;
30 }
31 void dfs(int x)
32 {
33 cnt++;//初始为0;这里是1了,从1开始编号;
34 Start[x]=cnt;//起点是x的编号
35 for(int i=head[x];i!=-1;i=edge[i].next)//遍历以v为起点的边;
36 {
37 dfs(edge[i].to);
38 }
39 End[x]=cnt;//遍历完子树后可以得到这个树根的编号范围就是star&end;
40 //dfs先根遍历,把x为根的子树的所有的节点编号在一段区间内,连续编号,并且记录该区间的编号起始和结束,当线段树修改值的时候就直接修改该区间;
41 }
42 void build(int rt,int l,int r)
43 {
44 tr[rt].l=l;
45 tr[rt].r=r;
46 tr[rt].val=-1;
47 tr[rt].lazy=0;
48 if(l==r)
49 return;
50 int mid=(l+r)/2;
51 build(rt<<1,l,mid);
52 build(rt<<1|1,mid+1,r);
53 }
54 void Pushdown(int rt)
55 {
56 int ls=rt<<1,rs=rt<<1|1;
57 if(tr[rt].lazy)
58 {
59 tr[rs].val=tr[ls].val=tr[rt].val;
60 tr[rs].lazy=tr[ls].lazy=1;
61 tr[rt].lazy=0;
62 }
63 }
64 void Update(int rt,int l,int r,int x)
65 {
66 if(tr[rt].l==l&&tr[rt].r==r)
67 {
68 tr[rt].val=x;
69 tr[rt].lazy=1;
70 return ;
71 }
72 Pushdown(rt);
73 int ls=rt<<1,rs=rt<<1|1;
74 if(l<=tr[ls].r)
75 {
76 if(r<=tr[ls].r)
77 Update(ls,l,r,x);
78 else
79 Update(ls,l,tr[ls].r,x);
80 }
81 if(r>=tr[rs].l)
82 {
83 if(l>=tr[rs].l)
84 Update(rs,l,r,x);
85 else
86 Update(rs,tr[rs].l,r,x);
87 }
88 }
89 int Query(int rt,int a)
90 {
91 if(tr[rt].l==a&&tr[rt].r==a)
92 {
93 return tr[rt].val;
94 }
95 Pushdown(rt);
96 int mid=(tr[rt].l+tr[rt].r)/2;
97 if(a<=mid)
98 return Query(rt<<1,a);
99 else
100 return Query(rt<<1|1,a);
101 }
102 int main()
103 {
104 int T,k=1;
105 cin>>T;
106 while(T--)
107 {
108 printf("Case #%d:\n",k++);
109 cnt=0;
110 tot=0;
111 memset(edge,0,sizeof(edge));
112 memset(head,-1,sizeof(head));
113 memset(Start,-1,sizeof(Start));
114 memset(End,-1,sizeof(End));
115 bool used[MAX_N];
116 memset(used,false,sizeof(used));
117 cin>>N;
118 for(int i=0;i<N-1;i++)
119 {
120 int u,v;
121 cin>>u>>v;//v是u的上级;
122 used[u]=true ;//表示u是有上级的,也就是有入度的;
123 Addedge(u,v);
124 }
125 for(int i=1;i<=N;i++)
126 {
127 if(!used[i])//找到入度为0的点,就是整个树的入口;
128 {
129 dfs(i);
130 break;
131 }
132 }
133 build(1,1,N);
134 cin>>M;
135 for(int i=0;i<M;i++)
136 {
137 char a[10];
138 scanf("%s",a);
139 if(a[0]=='C')
140 {
141 int x;
142 cin>>x;
143 int ans=Query(1,Start[x]);//该点的编号就是起点的编号;
144 cout<<ans<<endl;
145 }
146 else
147 {
148 int a,b;
149 cin>>a>>b;
150 Update(1,Start[a],End[a],b);
151 }
152 }
153
154 }
155 return 0;
156 }