一道dfs序+树状数组的题
因为并没有get到dfs序以及对树状数组也不熟练卡了很久orz
dfs序:
in和out是时间戳
dfs序可以将树转化成为一个序列,满足区间 -> 子树
然后就可以用树状数组之类的维护序列的东东来维护了
int idx = 0; void dfs(int u, int fa) { seq[++idx] = u; in[u] = idx; for(int i = head[u];i;i = nxt[i]) { int v = l[i]; if(v != fa) { dfs(v, u); } } out[u] = idx; }
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> using namespace std; const int SZ = 200010; const int INF = 1e9+10; int head[SZ], nxt[SZ], l[SZ], tot = 0; int in[SZ], out[SZ], seq[SZ], a[SZ]; void build(int f, int t) { l[++tot] = t; nxt[tot] = head[f]; head[f] = tot; } int idx = 0; void dfs(int u, int fa) { seq[++idx] = u; in[u] = idx; for(int i = head[u];i;i = nxt[i]) { int v = l[i]; if(v != fa) { dfs(v, u); } } out[u] = idx; } int d[SZ], n; void add(int i, int x) { for(; i <= n; i += (i & -i)) d[i] += x; } int get(int i) { int ans = 0; for(;i;i -= (i & -i)) ans += d[i]; return ans; } int query(int l, int r) { return get(r) - get(l - 1); } int main() { scanf("%d", &n); for(int i = 0; i < n-1; i++) { int x, y; scanf("%d %d", &x, &y); build(x, y); build(y, x); } dfs(1, 0); /*for(int i = 0; i < 11; i++) printf("%d ", in[i]); printf(" "); for(int i = 0; i < 11; i++) printf("%d ", out[i]); printf(" "); for(int i = 0; i < 25; i++) printf("%d ", seq[i]); printf(" ");*/ int m; scanf("%d", &m); for(int i = 1; i <= n; i++) add(i, 1), a[i] = 1; while(m--) { char op; int x; scanf("%c", &op); scanf("%c", &op); scanf("%d", &x); if(op == 'Q') printf("%d ", query(in[x], out[x])); if(op == 'C') { if(a[in[x]]) {a[in[x]] = 0; add(in[x], -1); } else {a[in[x]] = 1; add(in[x], 1); } } } return 0; }