题意:一棵树有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; }