ウォーターツリーCodeForces - 343D(チェーンスプリットツリー)

出力
標準出力

マッドサイエンティストマイクはで構成されてい根ざしツリー、建設した  n個の  頂点を。各頂点は、空または水で満たされたいずれかであることができるリザーバです。

ツリーの頂点が1から番号付けされている  N個の  各頂点の頂点1でルートと、その子のリザーバは、この頂点のリザーバの下に配置され、頂点を介してパイプで子供のそれぞれに接続されていますその水が下方に流れることができます。

マイクは、ツリーで、次の操作をしたいです:

  1. 頂点塗りつぶし  Vを  水で。そして、  V  とそのすべての子が水で満たされています。
  2. 空の頂点  Vそして、  V  とそのすべての祖先が空にされています。
  3. 頂点かどうかを決定します  vは  、現時点では水で満たされています。
最初は、ツリーのすべての頂点は空です。

マイクは、すでに彼は順番に実行したい操作の完全なリストをまとめました。木を使って実験する前に、マイクは、シミュレーションにより、リストを実行することを決めました。マイクは結果が、彼はすべての操作を実行した後に取得するかを決定に役立ちます。

入力

入力の最初の行は、整数含ま  N  (1≤  nは  ツリーの頂点の数を- 500000≤)。以下の各  N  - 1行は、2つのスペースで区切られた数字含ま  のI、  B I  (1≤  I、  bはiは  ≤  N、  I  ≠  B I) -木の縁。

次の行は、数字含ま  Q  (1つの≤  Q  実行する動作の数- 500000≤)を。以下の各  Qの  行は、二つのスペースで区切られた番号含有  CをI  (1≤  C I  ≤3)、  V I  (1≤  V iが  ≤  nが)、  C I  操作型である(文で与えられた番号付けに従います)、及び  V iは、  操作が行われた頂点です。

与えられたグラフが木であることが保証されています。

出力

頂点が空の場合、各タイプ3の運用別の行にプリント1頂点が一杯になった場合、および0。クエリが入力に与えられた順序でのクエリに対する回答を印刷します。

入力
コピー
5 
1 2
5 1
2 3
4 2
12
1 1
2 3
3 1
3 2
3 3
3 4
1 2
2 4
3 1
3 3
3 4
3 5
出力
コピー
0 
0
0
1
0
1
0
1


  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<algorithm>
  5 using namespace std;
  6 const int N=5e5+10;
  7 int sum[N*4],lazy[N*4];//线段树 
  8 int n,m,r,mod;//节点数,操作数,根节点,模数 
  9 int first[N],tot; //邻接表 
 10 //重儿子,每个节点新编号,父亲,编号,深度,子树个数,所在重链的顶部
 11 int son[N],id[N],fa[N],cnt,deep[N],size[N],top[N];
 12 int w[N],wt[N];// 初始点权,新编号点权
 13 int res=0;//查询答案
 14 
 15 struct edge{
 16     int v,next;
 17 }e[N*4]; 
 18 
 19 void add_edge(int u,int v){
 20     e[tot].v=v;
 21     e[tot].next=first[u];
 22     first[u]=tot++;
 23 }
 24 
 25 void init(){
 26     memset(first,-1,sizeof(first));
 27     tot=0;
 28     cnt=0;
 29 }
 30 
 31 int pushup(int rt){
 32     sum[rt]=(sum[rt*2]&&sum[rt*2+1]);
 33 }
 34 
 35 void pushdown(int rt,int m){
 36     if(lazy[rt]!=-1){
 37         lazy[rt*2]=lazy[rt];
 38         lazy[rt*2+1]=lazy[rt];
 39         sum[rt*2]=lazy[rt];
 40         sum[rt*2+1]=lazy[rt];
 41         lazy[rt]=-1;
 42     }
 43 }
 44 
 45 void build(int l,int r,int v){
 46     lazy[v]=-1;
 47     if(l==r){
 48         sum[v]=0;
 49         return ;
 50     }
 51     int mid=(l+r)/2;
 52     build(l,mid,v*2);
 53     build(mid+1,r,v*2+1);    
 54     pushup(v);
 55 }
 56 
 57 void update(int L,int R,int c,int l,int r,int rt){
 58     if(L<=l&&r<=R){
 59         lazy[rt]=c;
 60         sum[rt]=c;
 61         return;
 62     }
 63     pushdown(rt,r-l+1);
 64     int m=(l+r)/2;
 65     if(L<=m) update(L,R,c,l,m,rt*2);
 66     if(R>m) update(L,R,c,m+1,r,rt*2+1);
 67     pushup(rt);
 68 }
 69 
 70 
 71 void dfs1(int u,int f,int d){
 72     deep[u]=d;
 73     fa[u]=f;
 74     size[u]=1;
 75     int maxson=-1;
 76     for(int i=first[u];~i;i=e[i].next){
 77         int v=e[i].v;
 78         if(v==f) continue;
 79         dfs1(v,u,d+1);
 80         size[u]+=size[v];
 81         if(size[v]>maxson){
 82             son[u]=v;
 83             maxson=size[v];
 84         }
 85     }
 86 }
 87 
 88 void dfs2(int u,int topf){
 89     id[u]=++cnt;
 90     wt[cnt]=w[u];
 91     top[u]=topf;
 92     if(!son[u]) return ;
 93     dfs2(son[u],topf);
 94     for(int i=first[u];~i;i=e[i].next){
 95         int v=e[i].v;
 96         if(v==fa[u]||v==son[u]) continue;
 97         dfs2(v,v);
 98     }
 99 }
100 
101 
102 void updrange(int x,int y,int k){
103     while(top[x]!=top[y]){
104         if(deep[top[x]]<deep[top[y]]) swap(x,y);
105         update(id[top[x]],id[x],0,1,n,1);
106         x=fa[top[x]];
107     }
108     if(deep[x]>deep[y]) swap(x,y);
109     update(id[x],id[y],0,1,n,1);
110 }
111 
112 void upson(int x,int k){
113     update(id[x],id[x]+size[x]-1,1,1,n,1);
114 }
115 
116 int query(int L,int R,int l,int r,int rt){
117     if(L<=l&&r<=R){
118         return sum[rt];
119     }
120     pushdown(rt,r-l+1);
121     int m=(l+r)/2;
122     if(L<=m) return query(L,R,l,m,rt*2);
123     else if(R>m) return query(L,R,m+1,r,rt*2+1);
124 }
125 
126 
127 
128 
129 
130 
131 int main(){
132     int u,v;
133     scanf("%d",&n);
134     init();
135     for(int i=1;i<=n-1;i++){
136         scanf("%d%d",&u,&v);
137         add_edge(u,v);
138         add_edge(v,u);
139     }
140     dfs1(1,0,1);
141     dfs2(1,1);
142     build(1,n,1);
143     scanf("%d",&m);
144     while(m--){
145         int op,x,y,z;
146         scanf("%d",&op);
147         if(op==1){
148             scanf("%d",&x);
149             upson(x,1);
150         }
151         else if(op==2){
152             scanf("%d",&x);
153             updrange(1,x,0);
154         }
155         else if(op==3){
156             scanf("%d",&x);
157             if(query(id[x],id[x],1,n,1)==0) printf("0\n");
158             else printf("1\n");
159         }
 160      }
 161 }

ツリーは、チェーンを分割します、この質問は、次元削減の打撃であります

 

おすすめ

転載: www.cnblogs.com/ellery/p/11588586.html