题目的大意是给你一棵树,树上每个人都有自己的boss和员工,除了根节点,然后每当boss有一个编号为y的任务,boss就会把这个任务交给员工,这个boss的所有员工就都会接收到这个任务。然后有查询操作,问你现在这个员工的任务的编号是多少?
这道题我第一眼看是在看不出来怎么用线段树做,后来看了别人博客以后才知道我们要先把这个树转换成一个序列然后对序列进行线段树。对每个节点编号,然后这个节点有一个控制范围,这个控制范围一定是连续的,因为是棵树,然后我们对这个序列进行线段树就行
#include<iostream>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
using LL = int64_t;
const int maxn=5e4+5;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const LL LLINF=1e14;
const double pi=acos(-1.0);
bool used[maxn];
vector<int>E[maxn];
struct Node {
int l,r;
int lazy;
int task;
}tree[maxn*4];
int start[maxn],End[maxn];
int cnt=0;
void init() {
memset(used,false,sizeof(used));
for(int i=1;i<maxn;i++)E[i].clear();
cnt=0;
}
void dfs(int num) {
cnt++;
start[num]=cnt;
for(int i=0;i<E[num].size();i++) {
dfs(E[num][i]);
}
End[num]=cnt;
}
void build(int num,int l,int r) {
tree[num].l=l;tree[num].r=r;
tree[num].lazy=0;tree[num].task=-1;
if(l==r) return ;
int mid=(l+r)>>1;
build(num<<1,l,mid);
build(num<<1|1,mid+1,r);
}
void push_down(int num) {
if(tree[num].lazy) {
tree[num<<1].task=tree[num<<1|1].task=tree[num].task;
tree[num<<1].lazy=tree[num<<1|1].lazy=1;
tree[num].lazy=0;
}
}
void update(int num,int l,int r,int d) {
if(tree[num].l>=l&&tree[num].r<=r) {
tree[num].task=d;
tree[num].lazy=1;
return ;
}
push_down(num);
int mid=(tree[num].l+tree[num].r)>>1;
if(l<=mid) update(num<<1,l,r,d);
if(r>mid) update(num<<1|1,l,r,d);
}
int query(int num,int x) {
if(tree[num].l==x&&tree[num].r==x) return tree[num].task;
push_down(num);
int mid=(tree[num].l+tree[num].r)>>1;
if(x<=mid) return query(num<<1,x);
else return query(num<<1|1,x);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int T,kase=1;
cin>>T;
while(T--) {
int n,m;
init();
cout<<"Case #"<<kase++<<":\n";
cin>>n;
for(int i=1;i<n;i++) {
int u,v;
cin>>u>>v;
E[v].push_back(u);
used[u]=true;
}
for(int i=1;i<=n;i++) {
if(!used[i]) {
dfs(i);
break;
}
}
build(1,1,cnt);
cin>>m;
for(int i=1;i<=m;i++) {
char c;
cin>>c;
if(c=='C') {
int u;
cin>>u;
cout<<query(1,start[u])<<endl;
}
else {
int u,v;
cin>>u>>v;
update(1,start[u],End[u],v);
}
}
}
return 0;
}