社区讨论
样例过了,0分球条
P3178[HAOI2015] 树上操作参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mhj21xlw
- 此快照首次捕获于
- 2025/11/03 19:26 4 个月前
- 此快照最后确认于
- 2025/11/03 19:26 4 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = INT_MAX;
int n, m, len, cnt;
int f[100005], top[100005], id[100005], size[100005], son[100005], dep[100005];
ll w[100005], dfs[100005];
vector<int> G[100005];
struct node {
int l, r;
ll sum, add;
} tree[400005];
void dfs1(int u, int fa, int d) {
f[u] = fa, size[u] = 1, dep[u] = d;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v == fa) continue;
dfs1(v, u, d + 1);
size[u] += size[v];
if (size[v] > size[son[u]])
son[u] = v;
}
}
void dfs2(int u, int t) {
top[u] = t, id[u] = ++cnt, dfs[cnt] = w[u];
if (!son[u]) return;
dfs2(son[u], t);
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v != f[u] && v != son[u])
dfs2(v, v);
}
}
inline void pushup(int k) {
tree[k].sum = tree[k * 2].sum + tree[k * 2 + 1].sum;
}
inline void pushdown(int x) {
tree[x * 2].sum += tree[x].add * (tree[x * 2].r - tree[x * 2].l + 1);
tree[x * 2 + 1].sum += tree[x].add * (tree[x * 2 + 1].r - tree[x * 2 + 1].l + 1);
tree[x * 2].add += tree[x].add;
tree[x * 2 + 1].add += tree[x].add;
tree[x].add = 0;
}
void build(int now, int l, int r) {
tree[now].l = l, tree[now].r = r;
if (l == r) {
tree[now].sum = dfs[l];
return;
}
int mid = (l + r) / 2;
build(now * 2, l, mid);
build(now * 2 + 1, mid + 1, r);
pushup(now);
}
void add(int now, int x, int y, ll val) {
int l = tree[now].l, r = tree[now].r;
if (x <= l && r <= y) {
tree[now].add += val;
tree[now].sum += val * (tree[now].r - tree[now].l + 1);
return;
}
pushdown(now);
int mid = (l + r) / 2;
if (x <= mid) add(now * 2, x, y, val);
if (y > mid) add(now * 2 + 1, x, y, val);
pushup(now);
}
ll query(int now, int x, int y) {
int l = tree[now].l, r = tree[now].r;
if (x <= l && r <= y) return tree[now].sum;
pushdown(now);
int mid = (l + r) / 2;
ll ans = 0;
if (x <= mid) ans += query(now * 2, x, y);
if (y > mid) ans += query(now * 2 + 1, x, y);
return ans;
}
ll sumtree(int x, int y) {
int tx = top[x], ty = top[y];
ll ans = 0;
while (tx != ty) {
if (dep[tx] >= dep[ty]) {
ans += query(1, id[tx], id[x]);
x = f[tx], tx = top[x];
} else {
ans += query(1, id[ty], id[y]);
y = f[ty], ty = top[y];
}
}
if (id[x] <= id[y])
ans += query(1, id[x], id[y]);
else
ans += query(1, id[y], id[x]);
return ans;
}
inline void addtree(int x, int a) {
add(1, id[x], id[x] + size[x] - 1, a);
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%lld", &w[i]);
for (int i = 1; i < n; i++) {
int x, y;
scanf("%d%d", &x, &y);
G[x].push_back(y), G[y].push_back(x);
}
dfs1(1, 0, 1);
dfs2(1, 1);
build(1, 1, n);
while (m--) {
int op, x;
ll a;
scanf("%d%d", &op, &x);
if (op == 1) {
scanf("%lld", &a);
add(1, id[x], id[x], a);
} else if (op == 2) {
scanf("%lld", &a);
addtree(id[x], a);
} else {
printf("%lld\n", sumtree(1, x));
}
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...