题意:一个公司员工构成一个树型结构。有两种操作,给某人分工作(他会给自己的直接下属和间接下属分下去,新的工作会覆盖旧的工作),和查询某人当前的工作。
思路:欧拉序列+线段树。先建好树,dfs一次,求出欧拉序列,然后在这基础上建线段树更新和查询。其实这题模拟就可以过的。。。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#include <sstream>
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#include<time.h>
using namespace std;
#define INF 1000000
bool hasboss[50010];
vector<int> son[50010];
int oula[150010];
int L[150010];
int R[150010];
int end;
void dfs(int x){
int len=son[x].size();
oula[end++]=x;
for(int i=0;i<len;i++){
dfs(son[x][i]);
oula[end++]=x;
}
}
struct node{
int l;
int r;
int val;
bool flag;
};
node tree[450010];
void build_tree(int n,int l,int r){
tree[n].l=l; tree[n].r=r; tree[n].val=-1; tree[n].flag=1;
if(l==r)return;
int mid=(l+r)/2;
build_tree(n*2,l,mid);
build_tree(n*2+1,mid+1,r);
}
void update(int n,int l,int r,int v){
if(tree[n].l==l&&tree[n].r==r){
tree[n].val=v; tree[n].flag=1;
return;
}
int mid=(tree[n].l+tree[n].r)/2;
if(tree[n].flag){
update(n*2,tree[n].l,mid,tree[n].val);
update(n*2+1,mid+1,tree[n].r,tree[n].val);
}
if(r<=mid){
update(n*2,l,r,v);
}else{
if(l<=mid){
update(n*2,l,mid,v);
update(n*2+1,mid+1,r,v);
}else{
update(n*2+1,l,r,v);
}
}
tree[n].flag=0;
}
int query(int n,int l,int r){
if(tree[n].flag&&tree[n].l<=l&&tree[n].r>=r){
return tree[n].val;
}
int mid=(tree[n].l+tree[n].r)/2;
if(mid>=r){
return query(n*2,l,r);
}else{
if(mid<l){
return query(n*2+1,l,r);
}else{
return max(query(n*2,l,mid),query(n*2+1,mid+1,r));
}
}
}
int main(){
int t;
cin>>t;
int cas=0;
while(t--){
cas++;
memset(son,0,sizeof(son));
memset(hasboss,0,sizeof(hasboss));
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
end=1;
int n;
cin>>n;
int u,v;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
son[v].push_back(u);
hasboss[u]=1;
}
int root;
for(int i=1;i<=n;i++){
if(!hasboss[i]){
root=i;
break;
}
}
dfs(root);
for(int i=1;i<end;i++){
int cur=oula[i];
if(!L[cur])L[cur]=i;
R[cur]=i;
}
build_tree(1,1,end-1);
printf("Case #%d:\n",cas);
int M;
cin>>M;
for(int i=1;i<=M;i++){
char op;
cin>>op;
if(op=='C'){
int x;
scanf("%d",&x);
int ans=query(1,L[x],L[x]);
cout<<ans<<endl;
}else{
int x;
int y;
scanf("%d%d",&x,&y);
update(1,L[x],R[x],y);
}
}
}
return 0;
}