题意:
一棵树的结构,父节点是老板,子节点是员工,每次给父节点分配的任务,立即会下分到他所有的子节点,有更新和查询命令。
分析:
采用dfs序进行建树,可以很好的对区间进行修改和查询。
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
vector<int> g[maxn];
struct node{
int val;
bool mark;
}tree[maxn<<2];
bool vis[maxn];
int st[maxn];
int en[maxn];
int cnt;
void dfs(int u){
st[u]=++cnt;
for(int i=0;i<g[u].size();i++){
dfs(g[u][i]);
}
en[u]=cnt;
}
void build(int l,int r,int i){
tree[i].val=-1;
tree[i].mark=0;
if(l==r){
return;
}
int mid=l+r>>1;
build(l,mid,i<<1);
build(mid+1,r,i<<1|1);
}
inline void update(int i){
if(!tree[i].mark) return;
tree[i<<1].mark=tree[i<<1|1].mark=tree[i].mark;
tree[i<<1].val=tree[i<<1|1].val=tree[i].val;
tree[i].mark=0;
}
int query(int l,int r,int i,int t){
update(i);
if(l==r) return tree[i].val;
int mid=l+r>>1;
if(t<=mid) return query(l,mid,i<<1,t);
else return query(mid+1,r,i<<1|1,t);
}
void change(int tl,int tr,int l,int r,int i,int val){
if(tl>r||tr<l) return;
if(tl<=l&&r<=tr){
tree[i].val=val;
tree[i].mark=1;
return;
}
update(i);
int mid=l+r>>1;
change(tl,tr,l,mid,i<<1,val);
change(tl,tr,mid+1,r,i<<1|1,val);
}
int main(){
int T;
scanf("%d",&T);
for(int cs=1;cs<=T;cs++){
printf("Case #%d:\n",cs);
int n,m;
scanf("%d",&n);
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++) g[i].clear();
memset(tree,0,sizeof tree);
memset(st,0,sizeof st);
memset(en,0,sizeof en);
cnt=0;
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
g[v].push_back(u);
vis[u]=1;
}
for(int i=1;i<=n;i++){
if(!vis[i]){
dfs(i);
break;
}
}
build(1,cnt,1);
scanf("%d",&m);
while(m--){
char ch;
int x,y;
scanf(" %c",&ch);
if(ch=='C'){
scanf("%d",&x);
printf("%d\n",query(1,cnt,1,st[x]));
}else{
scanf("%d%d",&x,&y);
change(st[x],en[x],1,cnt,1,y);
}
}
}
return 0;
}