仔细想一下就发现就是dfs序上建线段树进行维护。。
建出这棵树的dfs序。(上下级关系)
每个节点掌控的区间为这个节点所在的子树(包括自己),由于是dfs,同一子树的结点的dfs序一定是连续的,即dfs序连续区间。
修改一个点,会把他的所有子孙所在结点全部赋值成一个值。就变成了dfs序的区间更新。
查询一个点,就直接查询这个点的dfs序就行。
//KX
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int M = 5e4+7;
#define ls o*2
#define rs o*2+1
#define pb push_back
int l[M],r[M];//每个点在线段树中影响的区间 一定连续,因为按dfs序建树
int ds[M];//每个点的dfs序
int fa[M];
int ru[M];
int head[M];
struct EDGE
{
int to,next,val;
}edge[M];
int cnt;
void add(int x,int y)
{
edge[++cnt].to=y;
// edge[cnt].val=w;
edge[cnt].next=head[x];
head[x]=cnt;
}
int dnt;//dfs序变量
int hi;//dfs深度
int mh;//最大深度
int size[M];
vector<int >vec[M];
void dfs(int x)//跑出每个点的dfs序--方便建线段树
{
hi++;
size[x]=1;
for(int i=head[x];i!=0;i=edge[i].next)//遍历x指向的点
{
int to=edge[i].to;
ds[to]=++dnt;
vec[hi].pb(to);//每层的结点编号
mh=max(mh,hi);
dfs(to);
size[x]+=size[to];
}
hi--;
}
int tag[M<<2],st[M<<2];
void pd(int o)
{
if(tag[o]==0)return ;
tag[ls]=tag[rs]=st[ls]=st[rs]=tag[o];
tag[o]=0;
}
void bd(int o,int l,int r)
{
tag[o]=0;st[o]=-1;
if(l==r)
return ;
int m=(l+r)/2;
bd(ls,l,m);
bd(rs,m+1,r);
}
void up(int o,int l,int r,int x,int y,int d)
{
if(x<=l&&r<=y)
{
st[o]=tag[o]=d;
return ;
}
pd(o);
int m=(l+r)/2;
if(x<=m)up(ls,l,m,x,y,d);
if(y>m)up(rs,m+1,r,x,y,d);
}
int qu(int o,int l,int r,int x)
{
if(l==r)
{
return st[o];
}
pd(o);
int m=(l+r)/2;
if(x<=m)return qu(ls,l,m,x);
return qu(rs,m+1,r,x);
}
int main()
{
int T;
scanf("%d",&T);
for(int t=1;t<=T;t++)
{
int n,u,v;
scanf("%d",&n);
//--
for(int i=1;i<=n;i++)ru[i]=0,fa[i]=i;
memset(head,0,sizeof(head));
dnt=cnt=0;
//--初始化
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
add(v,u);
fa[u]=v;
ru[u]++;//入度
}
int root;
for(int i=1;i<=n;i++)if(ru[i]==0)root=i;
ds[root]=++dnt;//根节点掌控全局
dfs(root);
size[root]=n;
for(int i=1;i<=n;i++)
l[i]=ds[i],r[i]=l[i]+size[i]-1;
int sz=dnt;
bd(1,1,sz);
/* for(int i=1;i<=sz;i++)
{
printf("+++ %d %d %d %d\n",i,ds[i],l[i],r[i]);
}*/
int m;
scanf("%d",&m);
printf("Case #%d:\n",t);
for(int i=1;i<=m;i++)
{
char ss[3];
scanf("%s",ss);
if(ss[0]=='C')
{
int x;
scanf("%d",&x);
// printf("ds:%d--\n",ds[x]);
printf("%d\n",qu(1,1,sz,ds[x]));//单点查询x对应的点
}
else
{
int x,d;
scanf("%d%d",&x,&d);
// printf("%d -- %d\n",l[x],r[x]);
up(1,1,sz,l[x],r[x],d);//区间更新结点x管辖的区间
}
}
}
return 0;
}