#include <bits/stdc++.h>
using namespace std ;

class SegmentTree {
private:
    int n ;
    vector<int> seg ;
    vector<int> lazy ;

public:
    SegmentTree(int n) {
        this -> n = n ;
        seg.resize((n << 2) + 1 , 0) ;
        lazy.resize((n << 2) + 1 , 0) ;
    }

    void build(int ind , int low , int high , vector<int>& arr) {
        if(low == high) {
            seg[ind] = arr[low] ;
            return ;
        }

        int mid = low + ((high - low) / 2) ;
        build((ind << 1) + 1 , low , mid , arr) ;
        build((ind << 1) + 2 , mid + 1 , high , arr) ;
        seg[ind] = seg[(ind << 1) + 1] + seg[(ind << 1) + 2] ;
    }

    int query(int ind , int qsi , int qei , int low , int high) {
        if (lazy[ind] != 0) {
            seg[ind] += (high - low + 1) * lazy[ind];

            if (low != high) {
                lazy[(ind << 1) + 1] += lazy[ind];
                lazy[(ind << 1) + 2] += lazy[ind];
            }

            lazy[ind] = 0;
        }
                
        // Case-1: No Overlap
        if(high < qsi || low > qei) {
            return 0 ;
        }

        // Case-2: Complete Overlap
        if(low >= qsi && high <= qei) {
            return seg[ind] ;
        }

        // Case-3: Partial Overlap
        int mid = low + ((high - low) / 2) ;
        int left = query((ind << 1) + 1 , qsi , qei , low , mid) ;
        int right = query((ind << 1) + 2 , qsi , qei , mid + 1 , high) ;
        return left + right ;
    }

    int query(int qsi , int qei) {
        return query(0 , qsi , qei , 0 , n - 1) ;
    }

    void pointUpdate(int updateInd , int val) {
        int curr = query(updateInd , updateInd) ;
        rangeUpdate(updateInd , updateInd , val - curr) ;
    }

    void rangeUpdate(int ind , int rangeLeft , int rangeRight , int inc , int low , int high) {
        // Update pending update if we visit the node think greedily that if we are visiting the node then update it naa in O(1) time so that in future we don't want to come specially to update it
        if(lazy[ind] != 0) {
            seg[ind] += (high - low + 1) * lazy[ind] ;

            // Propogate the updates down
            if (low != high) {
                lazy[(ind << 1) + 1] += lazy[ind];
                lazy[(ind << 1) + 2] += lazy[ind];
            }

            lazy[ind] = 0 ;
        }

        if(high < rangeLeft || low > rangeRight) {
            return ;
        }

        if(low >= rangeLeft && high <= rangeRight) {
            seg[ind] += (high - low + 1) * inc ;

            if(low != high) {
                lazy[(ind << 1) + 1] += inc ;
                lazy[(ind << 1) + 2] += inc ;
            }
            return ;
        }

        int mid = low + ((high - low) / 2) ;
        rangeUpdate((ind << 1) + 1 , rangeLeft , rangeRight , inc , low , mid) ;
        rangeUpdate((ind << 1) + 2 , rangeLeft , rangeRight , inc , mid + 1 , high) ;
        seg[ind] = seg[(ind << 1) + 1] + seg[(ind << 1) + 2] ;
    }

    void rangeUpdate(int rangeLeft , int rangeRight , int inc) {
        rangeUpdate(0 , rangeLeft , rangeRight , inc , 0 , n - 1) ;
    }
};

void solve() {
    int n ; cin >> n ;
    vector<int> arr(n) ;
    for(int i = 0 ; i < n ; i++) {
        cin >> arr[i] ;
    }
    SegmentTree st(n) ;
    st.build(0 , 0 , n - 1 , arr) ;

    int q ; cin >> q ;
    for(int Q = 0 ; Q < q ; Q++) {
        int type ; cin >> type ;

        // Type-1: Query
        if(type == 1) {
            int l , r ; cin >> l >> r ;
            cout << st.query(l , r) << endl ;
        }
        // Type-2: Point Update
        else if(type == 2) {
            int ind , val ; cin >> ind >> val ;
            st.pointUpdate(ind , val) ;
        }
        // Type-3: Range Update
        else if(type == 3) {
            int l , r , inc ; cin >> l >> r >> inc ;
            st.rangeUpdate(l , r , inc) ;
        }
    }
}

int main() {

    // freopen("input.txt" , "r" , stdin) ;
    // freopen("output.txt" , "w" , stdout) ;

    int t ; cin >> t ;
    while(t--) {
        solve() ;
    }
    return 0 ;
}