Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1、把某结点以及其各个祖先值设为0、询问某结点的值。
对于第一个操作就是经典的DFS序+线段树了。而对于第二个操作,考虑再维护一个域表示各个结点为根的子树是否有进行第二个操作,如果有那么该结点应该就要是0;而在进行第一个操作前,看一下子树是否有进行第二个操作,如果有就整个标记成没有并把标记上传,让该结点的父亲结点标记成进行了第二个操作。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define MAXN 555555 6 7 struct Edge{ 8 int v,next; 9 }edge[MAXN<<1]; 10 int NE,head[MAXN]; 11 void addEdge(int u,int v){ 12 edge[NE].v=v; edge[NE].next=head[u]; 13 head[u]=NE++; 14 } 15 16 int l[MAXN],r[MAXN],par[MAXN],dfn; 17 void dfs(int u,int fa){ 18 l[u]=++dfn; 19 for(int i=head[u]; i!=-1; i=edge[i].next){ 20 int v=edge[i].v; 21 if(v==fa) continue; 22 par[v]=u; 23 dfs(v,u); 24 } 25 r[u]=dfn; 26 } 27 28 int x,y,z,N; 29 bool tree[MAXN<<2],down[MAXN<<2],up[MAXN<<2]; 30 void updateUp(int i,int j,int k){ 31 if(x<=i && j<=y){ 32 up[k]=z; 33 return; 34 } 35 if(up[k]==0){ 36 up[k<<1]=0; 37 up[k<<1|1]=0; 38 } 39 int mid=i+j>>1; 40 if(x<=mid) updateUp(i,mid,k<<1); 41 if(y>mid) updateUp(mid+1,j,k<<1|1); 42 up[k]=up[k<<1]|up[k<<1|1]; 43 } 44 bool queryUp(int i,int j,int k){ 45 if(x<=i && j<=y){ 46 return up[k]; 47 } 48 if(up[k]==0){ 49 up[k<<1]=0; 50 up[k<<1|1]=0; 51 } 52 int mid=i+j>>1; bool res=0; 53 if(x<=mid) res|=queryUp(i,mid,k<<1); 54 if(y>mid) res|=queryUp(mid+1,j,k<<1|1); 55 return res; 56 } 57 58 void update(int i,int j,int k){ 59 if(x<=i && j<=y){ 60 tree[k]=z; 61 down[k]=z; 62 return; 63 } 64 if(down[k]==1){ 65 tree[k<<1]=1; 66 tree[k<<1|1]=1; 67 down[k<<1]=1; 68 down[k<<1|1]=1; 69 down[k]=0; 70 } 71 int mid=i+j>>1; 72 if(x<=mid) update(i,mid,k<<1); 73 if(y>mid) update(mid+1,j,k<<1|1); 74 } 75 bool query(int i,int j,int k){ 76 if(i==j){ 77 return tree[k]; 78 } 79 if(down[k]==1){ 80 tree[k<<1]=1; 81 tree[k<<1|1]=1; 82 down[k<<1]=1; 83 down[k<<1|1]=1; 84 down[k]=0; 85 } 86 int mid=i+j>>1; 87 if(x<=mid) return query(i,mid,k<<1); 88 else query(mid+1,j,k<<1|1); 89 } 90 91 int main(){ 92 int n,q,a,b; 93 scanf("%d",&n); 94 memset(head,-1,sizeof(head)); 95 for(int i=1; i<n; ++i){ 96 scanf("%d%d",&a,&b); 97 addEdge(a,b); 98 addEdge(b,a); 99 } 100 101 for(N=1; N<n; N<<=1); 102 dfs(1,1); 103 104 scanf("%d",&q); 105 while(q--){ 106 scanf("%d%d",&a,&b); 107 if(a==1){ 108 x=l[b]; y=r[b]; 109 if(queryUp(1,N,1)){ 110 z=0; 111 updateUp(1,N,1); 112 if(b!=1){ 113 x=l[par[b]]; y=l[par[b]]; z=1; 114 updateUp(1,N,1); 115 } 116 } 117 x=l[b]; y=r[b]; z=1; 118 update(1,N,1); 119 }else if(a==2){ 120 x=l[b]; y=l[b]; z=1; 121 updateUp(1,N,1); 122 }else if(a==3){ 123 x=l[b]; y=r[b]; 124 if(queryUp(1,N,1)){ 125 puts("0"); 126 }else{ 127 x=l[b]; y=l[b]; 128 printf("%d\n",query(1,N,1)); 129 } 130 } 131 } 132 return 0; 133 }