#pragma GCC optimize ("O3") #pragma GCC target ("avx") #include using namespace std; #define getchar getchar_unlocked #define putchar putchar_unlocked int in() { int n, c; while ((c = getchar()) < '0') if (c == EOF) return -1; n = c - '0'; while ((c = getchar()) >= '0') n = n * 10 + c - '0'; return n; } void putInt(int n) { int res[11], i = 0; do { res[i++] = n % 10, n /= 10; } while (n); while (i) putchar(res[--i] + '0'); putchar('\n'); } template class WeightedFenwickTree { private: struct Node { T sum0 = 0; T sum1 = 0; }; private: vector nodes; vector sumWeight; public: WeightedFenwickTree(vector weights) { const int n = weights.size(); nodes.resize(n + 1); sumWeight.resize(n + 1); for (int i = 0; i < n; i++) { sumWeight[i + 1] = sumWeight[i] + weights[i]; } } WeightedFenwickTree(vector weights, vector values) { const int n = weights.size(); nodes.resize(n + 1); sumWeight.resize(n + 1); for (int i = 0; i < n; i++) { nodes[i + 1].sum0 = values[i] * weights[i]; sumWeight[i + 1] = sumWeight[i] + weights[i]; } for (int i = 1; i <= n; i++) { if (i + (i & -i) <= n) { nodes[i + (i & -i)].sum0 += nodes[i].sum0; } } } private: void addPoint(int k, T v0, T v1) { k++; while (k < nodes.size()) { nodes[k].sum0 += v0; nodes[k].sum1 += v1; k += k & -k; } } T sum(int k) { k++; T res0 = 0; T res1 = 0; int x = k; while (k > 0) { res0 += nodes[k].sum0; res1 += nodes[k].sum1; k -= k & -k; } return res0 + res1 * sumWeight[x]; } public: T sum(int l, int r) { return sum(r - 1) - sum(l - 1); } void add(int l, int r, T value) { addPoint(l, -value * sumWeight[l], +value); addPoint(r, +value * sumWeight[r], -value); } }; template class CumulativeSum { private: vector s; public: CumulativeSum(vector a) : s(a.size() + 1) { for (int i = 0; i < a.size(); i++) { s[i + 1] = s[i] + a[i]; } } T sum(int l, int r) { return s[r] - s[l]; } }; struct ModInt { static const int mod = 1e9 + 7; int n; ModInt() : n(0) {} ModInt(int n) : n(n) {} int intValue() { return n; } ModInt operator+() const { return *this; } ModInt operator-() const { return ModInt(n == 0 ? 0 : mod - n); } ModInt &operator+=(const ModInt &r) { if ((n += r.n) >= mod) { n -= mod; } return *this; } ModInt operator+(const ModInt &r) const { ModInt res; res.n = n + r.n; if (res.n >= mod) { res.n -= mod; } return res; } ModInt &operator-=(const ModInt &r) { *this += -r; return *this; } ModInt operator-(const ModInt &r) const { return *this + (-r); } ModInt &operator*=(const ModInt &r) { n = 1LL * n * r.n % mod; return *this; } ModInt operator*(const ModInt &r) const { return ModInt(1LL * n * r.n % mod); } }; class HeavyLightDecomposition { private: const vector> &g; public: struct Node { int vid; int hid; int head; int parent; int heavy; }; vector nodes; vector> paths; HeavyLightDecomposition(const vector> &g) : g(g), nodes(g.size()) { dfs(0, -1); bfs(0); } void forEach(int u, int v, function f) { while (true) { if (nodes[u].head == nodes[v].head) { if (nodes[u].vid > nodes[v].vid) { swap(u, v); } f(nodes[u].hid, nodes[u].vid, nodes[v].vid); break; } else { if (nodes[u].hid < nodes[v].hid) { swap(u, v); } f(nodes[u].hid, nodes[nodes[u].head].vid, nodes[u].vid); u = nodes[nodes[u].head].parent; } } } private: int dfs(int curr, int prev) { nodes[curr].heavy = -1; nodes[curr].parent = prev; int maxSub = 0; int sub = 1; for (int next : g[curr]) { if (next == prev) { continue; } int subNext = dfs(next, curr); sub += subNext; if (maxSub < subNext) { maxSub = subNext; nodes[curr].heavy = next; } } return sub; } void bfs(int s) { queue q; q.push(s); while (!q.empty()) { int h = q.front(); q.pop(); vector path; for (int i = h; i != -1; i = nodes[i].heavy) { nodes[i].vid = path.size(); nodes[i].hid = paths.size(); nodes[i].head = h; path.push_back(i); for (int j : g[i]) { if (j != nodes[i].parent && j != nodes[i].heavy) { q.push(j); } } } paths.emplace_back(path); } } }; int main() { int n; cin >> n; vector s(n); vector c(n); for (int i = 0; i < n; i++) { s[i] = in(); } for (int i = 0; i < n; i++) { c[i] = in(); } vector> g(n); for (int i = 0; i < n - 1; i++) { int a = in() - 1; int b = in() - 1; g[a].push_back(b); g[b].push_back(a); } HeavyLightDecomposition hld(g); vector> ft; vector> csum; for (auto path : hld.paths) { vector ss(path.size()); vector cc(path.size()); for (int i = 0; i < path.size(); i++) { ss[i] = s[path[i]]; cc[i] = c[path[i]]; } csum.emplace_back(ss); ft.emplace_back(cc); } int q; cin >> q; for (int i = 0; i < q; i++) { int t; t = in(); if (t == 0) { int u = in() - 1; int v = in() - 1; int z = in(); hld.forEach(u, v, [&](int h, int l, int r) { ft[h].add(l, r + 1, z); }); } else { int u = in() - 1; int v = in() - 1; ModInt ans = 0; hld.forEach(u, v, [&](int h, int l, int r) { ans += ft[h].sum(l, r + 1); ans += csum[h].sum(l, r + 1); }); putInt(ans.intValue()); } } }