#include <bits/stdc++.h>   using namespace std;   using ll = long long;   static constexpr ll oo = numeric_limits<ll>::max() / 2;   struct Node {     ll sm, mx;     Node() : sm{0}, mx{-oo} {}     Node(ll sm_, ll mx_) : sm{sm_}, mx{mx_} {}   };   struct LazySegmentTree {     vector<Node> tree;     vector<ll> mark;     int n;     LazySegmentTree(vector<ll> a) : n(a.size()) {       tree.resize(4 * n);       mark.resize(4 * n, oo);       build(1, 0, n - 1, a);     }     Node merge(Node lhs, Node rhs) {       Node node;       node.sm = lhs.sm + rhs.sm;       node.mx = max(lhs.mx, rhs.mx);       return node;     }     void build(int v, int tl, int tr, const vector<ll>& a) {       if (tl == tr) {         tree[v] = {a[tl], a[tl]};         return;       }       int tm = (tl + tr) / 2;       build(2 * v, tl, tm, a);       build(2 * v + 1, tm + 1, tr, a);       tree[v] = merge(tree[2 * v], tree[2 * v + 1]);     }     void push(int v, int l, int r) {       if (mark[v] == oo) {         return;       }       int m = (l + r) / 2;       mark[2 * v] = mark[v];       tree[2 * v].mx = mark[v];       tree[2 * v].sm = (m - l + 1) * mark[v];       mark[2 * v + 1] = mark[v];       tree[2 * v + 1].mx = mark[v];       tree[2 * v + 1].sm = (r - m) * mark[v];       mark[v] = oo;     }     Node query(int l, int r) { return query(1, 0, n - 1, l, r); }     Node query(int v, int tl, int tr, int l, int r) {       if (l > r) return Node();       if (tl == l && tr == r) {         return tree[v];       }       push(v, tl, tr);       int tm = (tl + tr) / 2;       Node sl = query(2 * v, tl, tm, l, min(tm, r));       Node sr = query(2 * v + 1, tm + 1, tr, max(l, tm + 1), r);       return merge(sl, sr);     }     void assign(int lo, int hi, ll x) { return update(1, 0, n - 1, lo, hi, x); }     void update(int v, int tl, int tr, int l, int r, ll x) {       if (l > r) return;       if (tl == l && tr == r) {         mark[v] = x;         tree[v].mx = x;         tree[v].sm = (r - l + 1) * x;         return;       }       push(v, tl, tr);       int tm = (tl + tr) / 2;       update(2 * v, tl, tm, l, min(tm, r), x);       update(2 * v + 1, tm + 1, tr, max(l, tm + 1), r, x);       tree[v] = merge(tree[2 * v], tree[2 * v + 1]);     }   };   int main() {     ios_base::sync_with_stdio(0);     cin.tie(nullptr);     cout.tie(nullptr);     int n;     cin >> n;     vector<ll> a(n);     for (int i = 0; i < n; ++i) cin >> a[i];     vector<ll> b(n - 1);     for (int i = 0; i < n - 1; ++i) cin >> b[i];     vector<ll> t(n, 0);     for (int i = 1; i < n; ++i) {       t[i] = t[i - 1] + b[i - 1];     }     vector<ll> s(n);     s[0] = t[0];     for (int i = 1; i < n; ++i) s[i] = s[i - 1] + t[i];     auto sum = [&](const int lo, const int hi) -> ll {       if (lo > hi) return 0;       ll ret = s[hi];       if (lo > 0) {         ret -= s[lo - 1];       }       return ret;     };     vector<ll> c(n);     for (int i = 0; i < n; ++i) c[i] = a[i] - t[i];     LazySegmentTree tree(move(c));     int q;     cin >> q;     while (q-- > 0) {       char op;       cin >> op;       if (op ==  + ) {         int pos, x;         cin >> pos >> x;         if (x == 0) continue;         --pos;         auto node = tree.query(pos, pos);         ll d = node.mx + x;         int lo = pos, hi = n;         while (hi - lo > 1) {           int m = lo + (hi - lo) / 2;           node = tree.query(lo, m);           if (node.mx >= d) {             hi = m;           } else {             lo = m;           }         }         tree.assign(pos, lo, d);       } else {         int lo, hi;         cin >> lo >> hi;         --lo;         --hi;         auto node = tree.query(lo, hi);         cout << node.sm + sum(lo, hi) << endl;       }     }     return 0;   }