原题链接
考察:线段树
思路:
线段树染色+dfs序. 关于dfs序的讲解GO!
Code
#include <iostream>
#include <cstring>
using namespace std;
const int N = 50010;
int n,sz[N],h[N],idx,root,k,id[N],m,fa[N];
char s[3];
struct Road{
int fr,to,ne;
}road[N];
struct Node{
int l,r,c,tag;
}tr[N<<2];
void init()
{
memset(sz,0,sizeof sz); k = 0;
memset(fa,0,sizeof fa);
}
void add(int a,int b)
{
road[idx].to = b,road[idx].ne = h[a],h[a] = idx++;
}
int dfs(int u)
{
id[u] = ++k; sz[u] = 1;
for(int i=h[u];~i;i=road[i].ne)
{
int v = road[i].to;
sz[u]+=dfs(v);
}
return sz[u];
}
void push_up(int u)
{
if(tr[u<<1].c!=tr[u<<1|1].c) tr[u].c = -1;
else tr[u].c = tr[u<<1].c;
}
void push_down(int u)
{
if(tr[u].c!=-1)
{
tr[u<<1].c = tr[u].c;
tr[u<<1|1].c = tr[u].c;
}
}
void build(int u,int l,int r)
{
tr[u] = {l,r,0,0};
if(l==r) return;
int mid = l+r>>1;
build(u<<1,l,mid); build(u<<1|1,mid+1,r);
}
void modify(int u,int l,int r,int x)
{
if(tr[u].l>=l&&tr[u].r<=r)
{
tr[u].c = x;
tr[u].tag = x;
return;
}
push_down(u);
int mid = tr[u].l+tr[u].r>>1;
if(l<=mid) modify(u<<1,l,r,x);
if(mid<r) modify(u<<1|1,l,r,x);
push_up(u);
}
int query(int u,int idx)
{
if(tr[u].l<=idx&&tr[u].r>=idx&&tr[u].c!=-1) return tr[u].c;
if(tr[u].l==tr[u].r) return tr[u].c;
push_down(u);
int mid = tr[u].l+tr[u].r>>1;
if(idx<=mid) return query(u<<1,idx);
else return query(u<<1|1,idx);
}
int main()
{
int T,kcase = 0;
scanf("%d",&T);
while(T--)
{
init();
printf("Case #%d:\n",++kcase);
scanf("%d",&n); idx = 0;
for(int i=1;i<=n;i++) h[i] = -1;
for(int i=1;i<n;i++)
{
int u,v; scanf("%d%d",&u,&v);
add(v,u);
fa[u] = v;
}
for(int i=1;i<=n;i++) if(!fa[i]) {root=i;break;}
dfs(root);
build(1,1,n);
scanf("%d",&m);
while(m--)
{
int x,y;
scanf("%s%d",s,&x);
if(s[0]=='C')
{
int c = query(1,id[x]);
if(!c) puts("-1");
else printf("%d\n",c-1);
continue;
}
scanf("%d",&y);
y++;
modify(1,id[x],id[x]+sz[x]-1,y);
}
}
return 0;
}