Ideas:
The DFS sequence is actually something very water. Like the tree chain, it's a hash of the tree chain.
The problem is: Each subtree is assigned a value of 1, a point assignment of 0, the minimum value of the query subtree.
The question needs to be noted: When we assign a value of 1 to a subtrees tree, we have to query the value of the subtree before the minimum value is 0, if so, to make the subtree parent node becomes 0, or 0 of the information will be lost.
See the code for details:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include < string> #include <vector> #include <stack> #include <ctime> #include <bitset> #include < cstdlib> #include <cmath> #include <set> #include <list> #include <deque> #include <map > #include <queue> #define MAX (a) > (b)? ( A):(B) #define MIN (a) < (b) ( A):(B)) using namespace Std;typedef long long ll;typedef long double ld;const double eps = 1e-6;const double PI = ACOs (-1); const INT mod = 1000000000 + 7;const int INF = 0x3f3f3f3f;//& 0x7fffffffconst int seed = 131;const ll INF64 = LL (1e18 ); const int MAXN = 500000+10;int t,n,m,tot=0,in[maxn],out[maxn],minv[maxn<<2],setv[maxn<<2],pre[maxn]; vector<int> g[maxn];void dfs (int u, int fa) {In[u] = ++tot; Pre[u] = FA; int len = G[u].size (); for (int i = 0; i < len; i++) {int v = g[u][i]; if (v = = FA) continue; DfsV, u); } Out[u] = tot;} void pushup (int o) {Minv[o] = min (minv[o<<1], minv[o<<1|1]);} void pushdown (int l, int r, int o) {if (Setv[o]! =-1) {setv[o<<1] = setv[o<<1|1] = Setv[o]; MINV[O<<1] = minv[o<<1|1] = Setv[o]; Setv[o] =-1; }}void Build (int l, int r, int o) {Minv[o] = 0; Setv[o] =-1; if (L = = r) return; int mid = (L + r) >> 1; Build (L, Mid, o<<1); Build (Mid+1, R, o<<1|1);} void Update (int l, int r, int v, int l, int r, int o) {if (L <= l && R <= R) {Minv[o] = V; Setv[o] = v; return; } int mid = (L + r) >> 1; Pushdown (L, R, O); if (l <= mid) Update (L, R, V, L, Mid, o<<1); if (Mid < R) Update (L, R, V, Mid+1, R, O<<1|1); Pushup (o);} int query (int l, int r, int l, int r, int o) {if (L <= l && R <= R) {return minv[o]; } int mid = (L + r) >> 1; Pushdown (L, R, O); int ans = INF; if (L <= mid) ans = min (ans, query (L, R, L, Mid, o<<1)); if (Mid < r) ans = min (ans, query (L, R, Mid+1, R, O<<1|1)); Pushup (o); return ans;} int main () {scanf ("%d", &n); for (int i = 1; i < n; i++) {int u, v; scanf ("%d%d", &u, &v); G[u].push_back (v); G[v].push_back (U); } DFS (1, 0); Build (1, N, 1); int q; scanf ("%d", &q); while (q--) {int id, V; scanf ("%d%d", &id, &v); if (id = = 1) {int tmp = query (In[v], out[v], 1, N, 1); Update (In[v], out[v], 1, 1, N, 1); if (!tmp && pre[v]) update (IN[PRE[V]], In[pre[v]], 0, 1, N, 1); } else if (id = = 2) {update (IN[V], In[v], 0, 1, N, 1); } else {printf ("%d\n", Query (In[v], out[v], 1, N, 1)); }} return 0;}
Codeforces Round #200 (Div. 1) D. Water tree (Dfs sequence plus line segment trees)