The company usually assigns some tasks to some employees to finish.When a task is assigned to someone,He/She will assigned it to all his/her subordinates.In other words,the person and all his/her subordinates received a task in the same time. Furthermore,whenever a employee received a task,he/she will stop the current task(if he/she has) and start the new one.
Write a program that will help in figuring out some employee’s current task after the company assign some tasks to some employee.
For each test case:
The first line contains an integer N (N ≤ 50,000) , which is the number of the employees.
The following N - 1 lines each contain two integers u and v, which means the employee v is the immediate boss of employee u(1<=u,v<=N).
The next line contains an integer M (M ≤ 50,000).
The following M lines each contain a message which is either
"C x" which means an inquiry for the current task of employee x
or
"T x y"which means the company assign task y to employee x.
(1<=x<=N,0<=y<=10^9)
1 5 4 3 3 2 1 3 5 2 5 C 3 T 2 1 C 3 T 3 2 C 3
Case #1: -1 1 2
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=200000;
struct Node
{
int v;
int next;
};
Node G[maxn];
int p[maxn];
int l;
int in[maxn];
void init()
{
l=0;
memset(p,-1,sizeof(p));
memset(in,0,sizeof(in));
}
void addedge(int u,int v)
{
G[l].v=v;
G[l].next=p[u];
p[u]=l++;
}
int reach[maxn],leave[maxn];
int dfn;
void dfs(int u)
{
reach[u]=++dfn;
for(int i=p[u];i!=-1;i=G[i].next)
{
int t=G[i].v;
dfs(t);
}
leave[u]=++dfn;//?
}
struct Tree
{
int left,right;
int val;
};
Tree tree[maxn*3];
void buildtree(int id,int l,int r)
{
tree[id].left=l,tree[id].right=r;
tree[id].val=-1;
if(l!=r)
{
int mid=(l+r)>>1;
buildtree(id<<1,l,mid);
buildtree((id<<1)|1,mid+1,r);
}
}
void update(int id,int l,int r,int val)
{
if(tree[id].left==l&&tree[id].right==r)
{
tree[id].val=val;
return ;
}
if(tree[id].val!=-1)
{
tree[id<<1].val=tree[(id<<1)|1].val=tree[id].val;
tree[id].val=-1;
}
int mid=(tree[id].left+tree[id].right)>>1;
if(r<=mid) update(id<<1,l,r,val);
else if(l>mid) update((id<<1)|1,l,r,val);
else
{
update(id<<1,l,mid,val);
update((id<<1)|1,mid+1,r,val);
}
if(tree[id<<1].val==tree[(id<<1)|1].val)
tree[id].val=tree[id<<1].val;
}
int query(int id,int x)
{
if(tree[id].val!=-1)
{
return tree[id].val;
}
if(tree[id].left==tree[id].right)
{
return tree[id].val;
}
int mid=(tree[id].left+tree[id].right)>>1;
if(x<=mid) return query(id<<1,x);
else return query((id<<1)|1,x);
}
int main()
{
int ci,pl=1;scanf("%d",&ci);
while(ci--)
{
int n;scanf("%d",&n);
init();
for(int i=0;i<n-1;i++)
{
int u,v;scanf("%d%d",&u,&v);
addedge(v,u);
in[u]++;
}
int rot;
for(int i=1;i<=n;i++)
{
if(in[i]==0)
{
rot=i;break;
}
}
dfn=0;
dfs(rot);
buildtree(1,1,2*n);
printf("Case #%d:\n",pl++);
int q;scanf("%d",&q);
while(q--)
{
char str[3];scanf("%s",str);
if(str[0]=='T')
{
int x,y;scanf("%d%d",&x,&y);
update(1,reach[x],leave[x],y);
}
else
{
int x;scanf("%d",&x);
int cnt=query(1,leave[x]);
printf("%d\n",cnt);
}
}
}
return 0;
}