#include #include #include #include #include #include #include using namespace std; #pragma comment(linker, "/STACK:1024000000,1024000000") typedef __int64 LL; #define N 100100 #define lson (root<<1) #define rson (lson |1) int n, m,deep[N],fa[N],num[N],top[N]; int son[N]; int p[N]; LL tree[N *4]; LL ans[N *4]; bool Lazy[N *4]; int fp[N]; LL sq[N]; int Head[N]; int tot, pos; typedef struct { int next; int to; }Edge; Edge E[N * 2]; void Init() { for (int i = 0; i <= n; i++){ son[i] = -1; Head[i] = -1; } pos = 1; tot = 0; } void dfs2(int root, int Top) { top[root] = Top; p[root] = pos++; fp[p[root]] = root; if (son[root] == -1) return; dfs2(son[root], top[root]); for (int i = Head[root]; i != -1; i = E[i].next) { int u = E[i].to; if (u != son[root] && u != fa[root]) { dfs2(u, u); } } } void Build(int root, int L, int R) { ans[root] = 0; Lazy[root] = false; if (L == R) { tree[root] = sq[fp[L]]; return; } int mid = (L + R) >> 1; Build(lson, L, mid); Build(rson, mid+1, R); tree[root] = tree[lson] + tree[rson]; } void Add(int u, int v) { E[tot].to = v; E[tot].next = Head[u]; Head[u] = tot++; } void dfs1(int root, int pre, int Ceil) { deep[root] = Ceil; fa[root] = pre; num[root] = 1; for (int i = Head[root]; i != -1; i = E[i].next){ int u = E[i].to; if (u != pre){ dfs1(u, root, Ceil + 1); if (son[root] == -1 || num[son[root]] < num[u]) son[root] = u; num[root] += num[u]; } } } void Update(int root, int L, int R, int Ul, int Ur) { if (Lazy[root]) return; if (Ul <= L&&R <= Ur) { Lazy[root] = true; ans[root] = tree[root]; return; } int mid = (L + R) >> 1; if (Ur <= mid) Update(lson, L, mid, Ul,Ur); else if (Ul > mid) Update(rson, mid + 1, R, Ul, Ur); else { Update(lson, L, mid, Ul, mid); Update(rson, mid + 1, R, mid + 1, Ur); } ans[root] = ans[lson] + ans[rson]; } void Pushdown(int root) { Lazy[lson] = Lazy[rson] = true; ans[lson] = tree[lson]; ans[rson] = tree[rson]; Lazy[root] = false; } void PointU(int root, int L, int R, int pos) { if (L == R) { ans[root] = 0; Lazy[root] = false; return; } if (Lazy[root]) Pushdown(root); int mid = (L + R) >> 1; if (pos <= mid) PointU(lson, L, mid, pos); else PointU(rson, mid + 1,R ,pos); ans[root] = ans[lson] + ans[rson]; } void Modify(int uu, int v) { int f1 = top[uu]; int f2 = top[v]; while (f1 != f2) { if (deep[f1] < deep[f2]) { f1 ^= f2 ^= f1 ^= f2; uu ^= v ^= uu ^= v; } Update(1, 1, n, p[f1], p[uu]); uu = fa[f1]; f1 = top[uu]; } if (deep[uu]>deep[v]) uu ^= v ^= uu ^= v; Update(1, 1, n, p[uu], p[v]); } int main() { // freopen("in.txt", "r", stdin); int u, v; int t, i; scanf("%d", &t); while (t--) { scanf("%d",&n); Init(); for (i = 1; i <= n; i++) scanf("%I64d", &sq[i]); for (i = 1; i <= n - 1; i++) { scanf("%d%d", &u, &v); Add(u, v); Add(v, u); } dfs1(1, -1, 1); dfs2(1, 1); Build(1, 1, n); scanf("%d", &m); int op; while (m--) { scanf("%d", &op); if (op == 1) { scanf("%d%d", &u, &v); Modify(u, v); } else if (op == 2) { scanf("%d", &u); PointU(1, 1, n, p[u]); } else { scanf("%d", &u); v = p[u] + num[u] - 1; Update(1, 1, n, p[u], v); } printf("%I64d\n", ans[1]); } } return 0; }