题目:
公司里有从1到n共n个成员,除了董事长,每个人都有唯一一个直接上司。每个人都有若干下属,自己下属的下属仍然算作是自己的下属。当给某个成员分配工作时,该成员和其所有下属会立刻丢弃原来的工作,执行当前的工作。现在有两种操作(1)C x 查询成员x当前的工作内容(2)T x y为成员x分配新的任务y。对于每次查询操作输出相应的结果
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn = 5e4 + 10;
int t,m,n,a,b,c,q,k,cnt,u,v;
string str;
int tree[maxn<<2],ltree[maxn],rtree[maxn];//确定原来结点在线段树的区间
vector<int>pre[maxn];
bool vis[maxn];
void dfs(int pos){
ltree[pos] = ++cnt;//区间左端点
for(int i=0;i<pre[pos].size();i++){
dfs(pre[pos][i]);
}
rtree[pos] = cnt;//区间右端点
}
void push_down(int rt){
if(tree[rt] != -1){
tree[rt<<1] = tree[rt<<1|1] = tree[rt];
tree[rt] = -1;
}
}
void update(int c,int l,int r,int rt){
if(a<=l && b>=r){
tree[rt] = c;
return;
}
push_down(rt);
int mid = (l+r)>>1;
if(a<=mid) update(c,lson);
if(b>mid) update(c,rson);
}
int query(int l,int r,int rt){
if(l==r) return tree[rt];
push_down(rt);
int mid=(l+r) >> 1;
if(a<=mid) query(lson);
else query(rson);
}
int main(){
cin>>t;
for(int tt=1;tt<=t;tt++){
memset(tree,-1,sizeof(tree));
memset(vis,0,sizeof(vis));
memset(ltree,-1,sizeof(ltree));
memset(rtree,-1,sizeof(rtree));
cnt = 0;
scanf("%d",&n);
for(int i=1;i<=n;i++) pre[i].clear();
for(int i=1;i<=n-1;i++){
scanf("%d%d",&u,&v);
pre[v].push_back(u);
vis[u] = 1;
}
for(int i=1;i<=n;i++){
if(!vis[i]) dfs(i);
}
scanf("%d",&m);
printf("Case #%d:\n",tt);
while(m--){
cin>>str;
if(str[0] == 'C'){
scanf("%d",&u);
a=ltree[u];//左端点就是当前任务
printf("%d\n",query(1,n<<1,1));
}else{
scanf("%d%d",&u,&v);
a=ltree[u];
b=rtree[u];
update(v,1,n<<1,1);
}
}
}
return 0;
}