Water Tree(树链剖分+dfs时间戳)
Water Tree
http://codeforces.com/problemset/problem/343/D
Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a reservoir which can be either empty or filled with water.
The vertices of the tree are numbered from 1 to n with the root at vertex 1. For each vertex, the reservoirs of its children are located below the reservoir of this vertex, and the vertex is connected with each of the children by a pipe through which water can flow downwards.
Mike wants to do the following operations with the tree:
- Fill vertex v with water. Then v and all its children are filled with water.
- Empty vertex v. Then v and all its ancestors are emptied.
- Determine whether vertex v is filled with water at the moment.
Mike has already compiled a full list of operations that he wants to perform in order. Before experimenting with the tree Mike decided to run the list through a simulation. Help Mike determine what results will he get after performing all the operations.
The first line of the input contains an integer n (1 ≤ n ≤ 500000) — the number of vertices in the tree. Each of the following n - 1 lines contains two space-separated numbers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi) — the edges of the tree.
The next line contains a number q (1 ≤ q ≤ 500000) — the number of operations to perform. Each of the following q lines contains two space-separated numbers ci (1 ≤ ci ≤ 3), vi (1 ≤ vi ≤ n), where ci is the operation type (according to the numbering given in the statement), and vi is the vertex on which the operation is performed.
It is guaranteed that the given graph is a tree.
For each type 3 operation print 1 on a separate line if the vertex is full, and 0 if the vertex is empty. Print the answers to queries in the order in which the queries are given in the input.
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<cstring> 3 #include<string> 4 #include<cmath> 5 #include<cstdio> 6 #include<algorithm> 7 #include<vector> 8 #define maxn 500005 9 #define lson l,mid,rt<<1 10 #define rson mid+1,r,rt<<1|1 11 using namespace std; 12 13 int tree[maxn<<3],lazy[maxn<<3]; 14 int n; 15 int dep[maxn],fa[maxn],siz[maxn],son[maxn],id[maxn],top[maxn],cnt; 16 vector<int>ve[maxn]; 17 18 void pushup(int rt){ 19 if(tree[rt<<1]||tree[rt<<1|1]) 20 tree[rt]=1; 21 else 22 tree[rt]=0; 23 } 24 25 void pushdown(int rt){ 26 if(lazy[rt]!=-1){ 27 lazy[rt<<1]=lazy[rt]; 28 lazy[rt<<1|1]=lazy[rt]; 29 tree[rt<<1]=lazy[rt]; 30 tree[rt<<1|1]=lazy[rt]; 31 lazy[rt]=-1; 32 } 33 } 34 35 void build(int l,int r,int rt){ 36 lazy[rt]=-1; 37 if(l==r){ 38 tree[rt]=0; 39 return; 40 } 41 int mid=(l+r)/2; 42 build(lson); 43 build(rson); 44 pushup(rt); 45 } 46 47 void add(int L,int R,int k,int l,int r,int rt){ 48 if(L<=l&&R>=r){ 49 tree[rt]=k; 50 lazy[rt]=k; 51 return; 52 } 53 int mid=(l+r)/2; 54 pushdown(rt); 55 if(L<=mid) add(L,R,k,lson); 56 if(R>mid) add(L,R,k,rson); 57 pushup(rt); 58 } 59 60 int query(int L,int R,int l,int r,int rt){ 61 if(L<=l&&R>=r){ 62 return tree[rt]; 63 } 64 int mid=(l+r)/2; 65 pushdown(rt); 66 int ans=0; 67 if(L<=mid) if(ans||query(L,R,lson)) ans=1; 68 if(R>mid) if(ans||query(L,R,rson)) ans=1; 69 pushup(rt); 70 return ans; 71 } 72 73 void dfs1(int now,int f,int deep){ 74 dep[now]=deep; 75 siz[now]=1; 76 fa[now]=f; 77 int maxson=-1; 78 for(int i=0;i<ve[now].size();i++){ 79 if(ve[now][i]==f) continue; 80 dfs1(ve[now][i],now,deep+1); 81 siz[now]+=siz[ve[now][i]]; 82 if(siz[ve[now][i]]>maxson){ 83 maxson=siz[ve[now][i]]; 84 son[now]=ve[now][i]; 85 } 86 } 87 } 88 89 void dfs2(int now,int topp){ 90 id[now]=++cnt; 91 top[now]=topp; 92 if(!son[now]) return; 93 dfs2(son[now],topp); 94 for(int i=0;i<ve[now].size();i++){ 95 if(ve[now][i]==son[now]||ve[now][i]==fa[now]) continue; 96 dfs2(ve[now][i],ve[now][i]); 97 } 98 } 99 100 void addRange(int x,int y,int k){ 101 while(top[x]!=top[y]){ 102 if(dep[top[x]]<dep[top[y]]) swap(x,y); 103 add(id[top[x]],id[x],k,1,n,1); 104 x=fa[top[x]]; 105 } 106 if(dep[x]>dep[y]) swap(x,y); 107 add(id[x],id[y],k,1,n,1); 108 } 109 110 void addSon(int x,int k){ 111 add(id[x],id[x]+siz[x]-1,k,1,n,1); 112 } 113 114 int main(){ 115 std::ios::sync_with_stdio(false); 116 cin>>n; 117 int m; 118 int pos,z,x,y; 119 for(int i=1;i<n;i++){ 120 cin>>x>>y; 121 ve[x].push_back(y); 122 ve[y].push_back(x); 123 } 124 cnt=0; 125 dfs1(1,0,1); 126 dfs2(1,1); 127 build(1,n,1); 128 cin>>m; 129 for(int i=1;i<=m;i++){ 130 cin>>pos>>x; 131 if(pos==1){ 132 addSon(x,1); 133 } 134 else if(pos==2){ 135 addRange(1,x,0); 136 add(id[x],id[x],0,1,n,1); 137 } 138 else if(pos==3){ 139 if(query(id[x],id[x],1,n,1)){ 140 cout<<1<<endl; 141 } 142 else{ 143 cout<<0<<endl; 144 } 145 } 146 } 147 148 }
posted on 2018-09-26 00:05 Fighting_sh 阅读(713) 评论(0) 编辑 收藏 举报