/* 题意:给定点的上下级关系,规定如果给i分配任务a,那么它所有的下属(直接或间接)都得放弃手上任务开始进行任务a 给你一个序列,T a b,把任务b分配给a节点,C a 查询a正在进行的任务。 非常经典的线段树题目 从树的根节点向下递归并对每个节点i按序编号为level[i].l,在遍历完所有i的子节点后记录i的编号最多子节点的编号为level[i].r 此时level[i].l到level[i].r区间就是点i的覆盖区域(自身加所有子节点),给i分配任务就相当于对[level[i].l,level[i].r]操作 这就可以用线段树处理了 对于线段书某一个节点,用V记录它当前的任务,如果V==-1表示当前没有任务,对于查询a正在进行的任务,从根节点一直往下找,若 查询过程中有节点i的区间覆盖a控制的区间并V>-1,这个任务就是要找的任务,因为i释放V后必定覆盖a的区间,现在V没有释放,表示V的 子节点没有分配新的任务,所以V就是最新的任务 */ #include <algorithm> #include <iostream> #include <cstdio> #include<vector> #include <cstring> using namespace std; const int N=50005; int n,m,index; int out[N]; struct Node { int L,R,V;//区间的左端点和右端点及分配的任务 }nod[8*N]; void create(int t,int L,int R)//建树过程 { nod[t].L=L; nod[t].R=R; nod[t].V=-1; int mid=(L+R)>>1; if(L<R) { create(2*t,L,mid); create(2*t+1,mid+1,R); } } void down(int t)//向下释放任务 { if(nod[t].V==-1)return ; nod[2*t].V=nod[2*t+1].V=nod[t].V; nod[t].V=-1; } void insert(int t,int L,int R,int v) { //cout<<"tt"; int mid=(nod[t].L+nod[t].R)>>1; if(nod[t].L==L&&nod[t].R==R) { nod[t].V=v; return ; } down(t); if(R<=mid)insert(2*t,L,R,v); else if(L>mid)insert(2*t+1,L,R,v); else {insert(2*t,L,mid,v);insert(2*t+1,mid+1,R,v);} } int query(int t,int L) { int mid=(nod[t].L+nod[t].R)>>1; if(nod[t].V>-1||(nod[t].L==nod[t].R)) { return nod[t].V; } down(t); if(L<=mid)return query(2*t,L); else return query(2*t+1,L); } struct Level { int l,r; }level[N]; vector<int> node[N]; void dfs(int x) { index++; level[x].l=index; int size=node[x].size(); for(int i=0;i<size;i++) { dfs(node[x][i]); } level[x].r=index; } void init() { scanf("%d",&n); index=0; int a,b; for(int i=0;i<=n;i++) {node[i].clear(); out[i]=0;} for(int i=0;i<n-1;i++) { scanf("%d%d",&a,&b); out[a]++; node[b].push_back(a); } for(int i=1;i<=n;i++) if(out[i]==0) { dfs(i); break; } //cout<<index<<endl; } void solve(int ca) { printf("Case #%d:\n",ca); //cout<<index<<endl; create(1,1,index); scanf("%d",&m); char s[2]; int a,b; while(m--) { scanf("%s%d",s,&a); if(s[0]=='C') { printf("%d\n",query(1,level[a].l)); } else { scanf("%d",&b); insert(1,level[a].l,level[a].r,b); } } } int main() { int ca; scanf("%d",&ca); for(int i=1;i<=ca;i++) { init(); solve(i); } return 0; }