原题
n, a = int(input()), [0] + list(map(int, input().split()))
e = [[] for _ in range(n + 1)]
for _ in range(n - 1):
u, v = map(int, input().split())
e[u].append(v)
e[v].append(u)
size, dep, son, fa = [[0] * (n + 1) for _ in range(4)]
def dfs1(u):
size[u] = 1
son[u] = -1
for v in e[u]:
if v != fa[u]:
fa[v], dep[v] = u, dep[u] + 1
dfs1(v)
size[u] += size[v]
if son[u] == -1 or size[v] > size[son[u]]:
son[u] = v
dfn, tid, top = [[0] * (n + 1) for _ in range(3)]
cnt = 0
def dfs2(u, t):
global cnt
top[u] = t
cnt += 1
dfn[u], tid[cnt] = cnt, u
if son[u] == -1:
return
dfs2(son[u], t)
for v in e[u]:
if v != fa[u] and v != son[u]:
dfs2(v, v)
dfs1(1)
dfs2(1, 1)
tr, lz = [[0] * (4 * n) for _ in range(2)]
def pushup(o):
tr[o] = tr[o << 1] + tr[o << 1 | 1]
def pushdown(o, olen):
if lz[o]:
lson, rson = o << 1, o << 1 | 1
lz[lson] += lz[o]
lz[rson] += lz[o]
tr[lson] += (olen + 1) // 2 * lz[o]
tr[rson] += olen // 2 * lz[o]
lz[o] = 0
def build(o, l, r):
if l == r:
tr[o] = a[tid[l]]
return
lson, rson, mid = o << 1, o << 1 | 1, (l + r) >> 1
build(lson, l, mid)
build(rson, mid + 1, r)
pushup(o)
build(1, 1, n)
def update(o, l, r, i, j, k):
if i == l and j == r:
lz[o] += k
tr[o] += (r - l + 1) * k
return
lson, rson, mid = o << 1, o << 1 | 1, (l + r) >> 1
pushdown(o, r - l + 1)
if j <= mid:
update(lson, l, mid, i, j, k)
elif i > mid:
update(rson, mid + 1, r, i, j, k)
else:
update(lson, l, mid, i, mid, k)
update(rson, mid + 1, r, mid + 1, j, k)
pushup(o)
def query(o, l, r, i, j):
if i == l and j == r:
return tr[o]
lson, rson, mid = o << 1, o << 1 | 1, (l + r) >> 1
pushdown(o, r - l + 1)
if j <= mid:
return query(lson, l, mid, i, j)
elif i > mid:
return query(rson, mid + 1, r, i, j)
else:
return query(lson, l, mid, i, mid) + \
query(rson, mid + 1, r, mid + 1, j)
def update_range(u, v, k):
while top[u] != top[v]:
if dep[top[u]] < dep[top[v]]:
u, v = v, u
update(1, 1, n, dfn[top[u]], dfn[u], k)
u = fa[top[u]]
if dep[u] > dep[v]:
u, v = v, u
update(1, 1, n, dfn[u], dfn[v], k)
def query_range(u, v):
ans = 0
while top[u] != top[v]:
if dep[top[u]] < dep[top[v]]:
u, v = v, u
ans += query(1, 1, n, dfn[top[u]], dfn[u])
u = fa[top[u]]
if dep[u] > dep[v]:
u, v = v, u
ans += query(1, 1, n, dfn[u], dfn[v])
return ans
m = int(input())
for _ in range(m):
op = list(map(int, input().split()))
if op[0] == 1:
u, v, k = op[1:]
update_range(u, v, k)
elif op[0] == 2:
u, k = op[1:]
update(1, 1, n, dfn[u], dfn[u] + size[u] - 1, k)
elif op[0] == 3:
u, v = op[1:]
print(query_range(u, v))
else:
u = op[-1]
print(query(1, 1, n, dfn[u], dfn[u] + size[u] - 1))