P3178 [HAOI2015]树上操作 样例没过,luogu提交中RE。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
#define int long long
int n, q, x, y, z, opt, a[N], b[N];
namespace ordinary {
inline void chkmax(int &x, int y) {x = max(x, y);}
inline void chkmin(int &x, int y) {x = min(x, y);}
template <typename T> inline void read(T &x){
x = 0; int f = 1; char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
x *= f;
}
template<typename _T, typename ...Args> inline void read (_T &x, Args &...args) { read(x), read(args...); }
template<typename T_> inline void write(T_ x) {
if (x < 0) putchar('-'), x = -x;
if (9 < x) write(x / 10);
putchar(x % 10 + '0');
}
template<typename _T, typename ...Args> inline void write (const _T &x, const Args &...args) { write(x), write(args...);}
};
using namespace ordinary;
struct Segment_Tree {
struct node {
int l, r, sum, lazy;
}t[N << 2];
inline void pushup(int x) {t[x].sum = t[x << 1].sum + t[x << 1 | 1].sum;}
inline void pushdown(int x) {
if (t[x].lazy) {
t[x << 1].sum += t[x].lazy * (t[x << 1].r - t[x << 1].l + 1);
t[x << 1 | 1].sum += t[x].lazy * (t[x << 1 | 1].r - t[x << 1 | 1].l + 1);
t[x << 1].lazy += t[x].lazy, t[x << 1 | 1].lazy += t[x].lazy, t[x].lazy = 0;
}
}
inline void build(int x, int l, int r) {
t[x].l = l, t[x].r = r;
if (l == r) {
t[x].sum = a[l];
return ;
}
int mid = l + r >> 1;
build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r);
pushup(x);
}
inline void update(int x, int l, int r, int val) {
if (l <= t[x].l && t[x].r <= r) {
t[x].sum += val * (t[x].r - t[x].l + 1), t[x].lazy += val;
return ;
}
pushdown(x);
int mid = t[x].l + t[x].r >> 1;
if (l <= mid) update(x << 1, l, r, val);
if (mid < r) update(x << 1 | 1, l, r, val);
pushup(x);
}
inline int Get_sum(int x, int l, int r) {
if (l <= t[x].l && t[x].r <= r) return t[x].sum;
pushdown(x);
int mid = t[x].l + t[x].r >> 1, ans = 0;
if (l <= mid) ans += Get_sum(x << 1, l, r);
if (mid < r) ans += Get_sum(x << 1 | 1, l, r);
return ans;
}
}T;
struct Heavy_Light_Decomposition {
vector<int> G[N];
int dep[N], hson[N], lens[N], fa[N], dfn[N], top[N], tot;
inline void dfs1(int pre, int x, int cnt) {
int len = G[x].size();fa[x] = pre, dep[x] = cnt, lens[x] = 1;
for (int i = 0;i < len;i++) {
if (G[x][i] == pre) continue;
dfs1(x, G[x][i], cnt + 1);
lens[x] += lens[G[x][i]];
if (lens[G[x][i]] > lens[hson[x]]) hson[x] = G[x][i];
}
}
inline void dfs2(int x, int cnt) {
int len = G[x].size();top[x] = cnt, dfn[x] = ++tot;
if (!hson[x]) return ;
dfs2(hson[x], cnt);
for (int i = 0;i < len;i++) {
if (G[x][i] == fa[x] || G[x][i] == hson[x]) continue;
dfs2(G[x][i], G[x][i]);
}
}
inline int query(int x, int y) {
int ans = 0;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
ans += T.Get_sum(1, dfn[top[x]], dfn[x]);
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
ans += T.Get_sum(1, dfn[x], dfn[y]);
return ans;
}
}Tree;
signed main() {
read(n);
for (int i = 1;i <= n;i++) read(b[i]);
for (int i = 1;i < n;i++) read(x, y), Tree.G[x].push_back(y), Tree.G[y].push_back(x);
Tree.dfs1(-1, 1, 1), Tree.dfs2(1, 1);
for (int i = 1;i <= n;i++) a[Tree.dfn[i]] = b[i];
T.build(1, 1, n), read(q);
while(q--) {
read(opt, x);
if (opt == 1) read(y), T.update(1, Tree.dfn[x], Tree.dfn[x], y);
else if (opt == 2) read(y), T.update(1, Tree.dfn[x], Tree.dfn[x] + Tree.lens[x] - 1, y);
else write(Tree.query(1, x)), puts("");
}
return 0;
}