dfs序
dfs序真神奇
dfs求出入栈时刻和出栈时刻,然后在in和out分别打上1和-1就能统计路径和了。
其实这里dfs序能够让我们求一个点处于哪些节点的子树内,而一个节点只处于从自己到跟路径的节点的。
这里的dfs序有些像括号序列,如果一个点不在另一个点的子树内,那么也就不在另一个点的括号内,那么另一个点的括号也闭合了,+1-1抵消
#include<bits/stdc++.h> using namespace std; const int N = 250010; int n, m, top, cnt; int st[N], in[N], out[N]; vector<int> G[N]; struct BIT { int tree[N << 1]; int lowbit(int i) { return i & (-i); } void update(int pos, int delta) { for(int i = pos; i <= n * 2 + 1; i += lowbit(i)) tree[i] += delta; } int query(int pos) { int ret = 0; for(int i = pos; i; i -= lowbit(i)) ret += tree[i]; return ret; } } t; void dfs(int u, int last) { in[u] = ++cnt; for(int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if(v == last) continue; dfs(v, u); } out[u] = ++cnt; } 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); scanf("%d", &m); for(int i = 2; i <= n; ++i) { t.update(in[i], 1); t.update(out[i], -1); } for(int i = 1; i < n + m; ++i) { char opt[10]; int u, v; scanf("%s", opt); if(opt[0] == 'A') { scanf("%d%d", &u, &v); t.update(in[v], -1); t.update(out[v], 1); } if(opt[0] == 'W') { scanf("%d", &u); printf("%d ", t.query(in[u])); } } return 0; }