华华和月月种树
思路
树上对整颗子树进行操作,容易想到用序,但是这是一颗动态变化的树,所以我们可以考虑离线操作。
既然是离线操作,那就简单了,先存下一整棵树以及所有的操作,然后按照要求模拟即可:
- 对于操作二我们直接以最终一整颗树中形态来进行差分。
- 对于操作一这里就有有一个关键点了,这个时候刚好有一个点加入树里面,因此我们需要记录这个节点初始的,方便后面输出单个节点的权值。
- 操作三,我们就可以直接输出这个时候第一步记录的值在这里就排上用场了。
代码
/* Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> #define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f; inline ll read() { ll f = 1, x = 0; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f * x; } const int N = 1e5 + 10; struct Node { int op, a, b; Node(int _op = 0, int _a = 0, int _b = 0) : op(_op), a(_a), b(_b) {} }; vector<Node> a; vector<int> G[N]; int r[N], l[N], tot; int tree[N], n, m, value[N]; void dfs(int rt, int fa) { l[rt] = ++tot; for(int i : G[rt]) { if(i == fa) continue; dfs(i, rt); } r[rt] = tot; } int lowbit(int x) { return x & (-x); } void update(int rt, int x) { while(rt <= tot) { tree[rt] += x; rt += lowbit(rt); } } int query(int rt) { int ans = 0; while(rt) { ans += tree[rt]; rt -= lowbit(rt); } return ans; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); m = read(), n = 0; for(int i = 1; i <= m; i++) { int op = read(); if(op == 1) { int x = read(); G[x].pb(++n); G[n].pb(x); a.pb(Node(op, x, n)); } else if(op == 2) { int x = read(), y = read(); a.pb(Node(op, x, y)); } else { int x = read(); a.pb(Node(op, x)); } } dfs(0, -1); for(auto i : a) { int op = i.op; if(op == 1) { value[i.b] = query(l[i.b]); } else if(op == 2) { update(r[i.a] + 1, -i.b); update(l[i.a], i.b); } else { printf("%d\n", query(l[i.a]) - value[i.a]); } } return 0; }