华华和月月种树
思路
树上对整颗子树进行操作,容易想到用序,但是这是一颗动态变化的树,所以我们可以考虑离线操作。
既然是离线操作,那就简单了,先存下一整棵树以及所有的操作,然后按照要求模拟即可:
- 对于操作二我们直接以最终一整颗树中形态来进行差分
。
- 对于操作一这里就有有一个关键点了,这个时候刚好有一个点加入树里面,因此我们需要记录这个节点初始的
,方便后面输出单个节点的权值。
- 操作三,我们就可以直接输出
这个时候第一步记录的值在这里就排上用场了。
代码
/*
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;
} 
京公网安备 11010502036488号