题意:一棵树有N个节点,有三种操作(1)“1 v",表示将以点v为根节点的子树全部赋值为1,(2)"2 v",表示将点v以及点v的所有祖先节点全部赋值为0,(3)"3 v",表示查询点v的值。
将树型转线性之后,我用了两棵线段树去维护这两种操作,明显可知的是,点v的子树里有一个点进行了操作(2),并且点v进行操作(1)(如果有)的时间早于操作2,那么点v的值就为0,在线段树里维护好每个操作的时间就可以了。
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=500005;
struct Edge
{
int v,pre;
Edge(){}
Edge(int v,int pre) :
v(v),pre(pre) {}
}edge[N*3];
int n,m;
int head[N],nEdge;
int low[N],high[N],idx;
void edgeInit()
{
nEdge=0;
memset(head,-1,sizeof(head));
}
void addEdge(int u,int v)
{
edge[nEdge]=Edge(v,head[u]);
head[u]=nEdge++;
}
void dfs(int u,int pre)
{
low[u]=++idx;
for(int i=head[u];i!=-1;i=edge[i].pre)
{
int v=edge[i].v;
if(v==pre) continue;
dfs(v,u);
}
high[u]=idx;
}
struct Segtree
{
int delay[N*4],mx[N*4];
void fun(int ind,int valu){ mx[ind]=delay[ind]=valu; }
void PushDown(int ind)
{
if(delay[ind])
{
fun(LL(ind),delay[ind]);
fun(RR(ind),delay[ind]);
delay[ind]=0;
}
}
void PushUp(int ind)
{
mx[ind]=max(mx[LL(ind)],mx[RR(ind)]);
}
void build(int lft,int rht,int ind)
{
delay[ind]=0;
if(lft!=rht)
{
int mid=MID(lft,rht);
build(lft,mid,LL(ind));
build(mid+1,rht,RR(ind));
}
}
void updata(int st,int ed,int valu,int lft,int rht,int ind)
{
if(st<=lft&&rht<=ed) fun(ind,valu);
else
{
PushDown(ind);
int mid=MID(lft,rht);
if(st<=mid) updata(st,ed,valu,lft,mid,LL(ind));
if(ed> mid) updata(st,ed,valu,mid+1,rht,RR(ind));
PushUp(ind);
}
}
int query(int st,int ed,int lft,int rht,int ind)
{
if(st<=lft&&rht<=ed) return mx[ind];
else
{
PushDown(ind);
int mid=MID(lft,rht);
int mx1=0,mx2=0;
if(st<=mid) mx1=query(st,ed,lft,mid,LL(ind));
if(ed> mid) mx2=query(st,ed,mid+1,rht,RR(ind));
PushUp(ind);
return max(mx1,mx2);
}
}
}seg1,seg2;
int main()
{
while(scanf("%d",&n)!=EOF)
{
edgeInit(); idx=0;
for(int i=1;i<n;i++)
{
int a,b; scanf("%d%d",&a,&b);
addEdge(a,b); addEdge(b,a);
}
dfs(1,-1);
seg1.build(1,idx,1); seg2.build(1,idx,1);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int a,u; scanf("%d%d",&a,&u);
if(a==1) seg1.updata(low[u],high[u],i,1,idx,1);
else if(a==2) seg2.updata(low[u],low[u],i,1,idx,1);
else
{
int tmp1=seg1.query(low[u],low[u],1,idx,1);
int tmp2=seg2.query(low[u],high[u],1,idx,1);
if(tmp1>tmp2) puts("1");
else puts("0");
}
}
}
return 0;
}