#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <ctime>
#include <cstring>
#include <cassert>
#include <bitset>
#include <sstream>
#include <queue>

using namespace std;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) int(a.size() - 1)
#define all(a) a.begin(), a.end()
#define seta(a,x) memset (a, x, sizeof (a))
#define I (int)

typedef long long int64;
typedef pair <int, int> pii;
typedef long double ldb;

const long double eps = 1e-9;
const int inf = (1 << 30) - 1;
const int64 inf64 = ((int64)1 << 62) - 1;
const long double pi = 3.1415926535897932384626433832795;

template <class T> T sqr (T x) {return x * x;}
template <class T> T abs (T x) {return x < 0 ? -x : x;}

const int kmax = 21;
const int nmax = 1 << 17;

struct vertex {
    int dp[kmax][2][2];

    void init() {
        forn(i, kmax)
            forn(j, 2)
                forn(k, 2)
                    dp[i][j][k] = -1e9;

        dp[0][0][0] = 0;
    }

    vertex() {
        init();
    }

    vertex(int x) {
        init();
        dp[1][1][1] = max(dp[1][1][1], x);
    }
};

void merge (vertex & res, vertex a, const vertex &b) {
    res.init();

    forn(f11, 2)
    forn(f22, 2) {
        forn(i, kmax)
        if (max(a.dp[i][f11][0], a.dp[i][f11][1]) > -1e9)
            for (int j = 0; i + j <= kmax; j ++) {
                if (i + j < kmax)
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], max(a.dp[i][f11][0] + max(b.dp[j][0][f22], b.dp[j][1][f22]),
                                                                    a.dp[i][f11][1] + b.dp[j][0][f22]));
                if (i > 0 && j > 0)
                    res.dp[i+j - 1][f11][f22] = max(res.dp[i+j-1][f11][f22], a.dp[i][f11][1] + b.dp[j][1][f22]);
            }
        forn(i, kmax)
            if (res.dp[i][f11][f22] < -1e8)
                res.dp[i][f11][f22] = -1e9;
    }

/*
    forn(i, kmax)
        forn(f11, 2)
            if (max(a.dp[i][f11][0], a.dp[i][f11][1]) > -1e9)
        for (int j = 0; i + j <= kmax; j ++)
        forn(f22, 2) {
            if (i + j < kmax) {
                res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][0] + b.dp[j][0][f22]);
                res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][0] + b.dp[j][1][f22]);
                res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][1] + b.dp[j][0][f22]);
            }
            if (i > 0 && j > 0)
                res.dp[i+j - 1][f11][f22] = max(res.dp[i+j-1][f11][f22], a.dp[i][f11][1] + b.dp[j][1][f22]);
        }

        */
    /*
    forn(i, kmax)
    forn(f11, 2)
        if (a.dp[i][f11][0] > -1e9)
            for (int j = 0; i + j <= kmax; j ++)
            forn(f22, 2) {
                if (i + j < kmax) {
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][0] + b.dp[j][0][f22]);
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][0] + b.dp[j][1][f22]);
                }
            }
    forn(i, kmax)
    forn(f11, 2)
        if (a.dp[i][f11][1] > -1e9)
            for (int j = 0; i + j <= kmax; j ++)
            forn(f22, 2) {
                if (i + j < kmax) {
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][1] + b.dp[j][0][f22]);
                }
                if (i > 0 && j > 0)
                    res.dp[i+j - 1][f11][f22] = max(res.dp[i+j-1][f11][f22], a.dp[i][f11][1] + b.dp[j][1][f22]);
            }   */
}

int n, m;
vertex t[nmax*2];
vertex res;
int a[nmax];

void update(int v, int l, int r, int c, int x) {
    if (c > r || c < l) return;
    if (l == r) {
        t[v] = vertex(x);
        return;
    }
    int m = (l + r) / 2;
    update(v * 2, l, m, c, x);
    update(v * 2 + 1, m + 1, r, c, x);
    merge(t[v], t[v*2], t[v*2 + 1]);
}

void build(int v, int l, int r, int n) {
    if (l > n) return;
    if (l == r) {
        t[v] = vertex(a[l-1]);
        return;
    }
    int m = (l + r) / 2;
    build(v * 2, l, m, n);
    build(v * 2 + 1, m + 1, r, n);
    merge(t[v], t[v*2], t[v*2 + 1]);
    //cerr << "34";
}

void get(int v, int l, int r, int l1, int r1) {
    if (l > r1 || r < l1) return;
    if (l1 <= l && r <= r1) {
        merge(res, res, t[v]);
        return;
    }
    int m = (l + r) / 2;
    get(v * 2, l, m, l1, r1);
    get(v * 2 + 1, m + 1, r, l1, r1);
}

int get(int l, int r, int k) {
    res.init();
    get(1, 1, nmax, l, r);
    int re = 0;
    forn(k1, k+1)
        forn(i, 2)
                forn(j, 2)
                re = max(re, res.dp[k1][i][j]);
    return re;
}

int main ()
{
//  freopen("input.txt", "rt", stdin);
//  freopen("out", "wt", stdout);
    cin >> n;
    forn(i, n)
        scanf("%d", &a[i]);
//  cerr << clock() << endl;
    build(1, 1, nmax, n);
    cerr << clock() << endl;
//  return 0;
    cin >> m;
    forn(i, m) {
        int x, l, r, k;
        scanf("%d %d %d", &x, &l, &r);
        if (x == 0) {
            update(1, 1, nmax, l, r);
            continue;
        } else {
            scanf("%d", &k);
            printf("%d\n", get(l, r, k));
        }
    }

    cerr << clock() << endl;

    return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <ctime>
#include <cstring>
#include <cassert>
#include <bitset>
#include <sstream>
#include <queue>

using namespace std;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) int(a.size() - 1)
#define all(a) a.begin(), a.end()
#define seta(a,x) memset (a, x, sizeof (a))
#define I (int)

typedef long long int64;
typedef pair <int, int> pii;
typedef long double ldb;

const long double eps = 1e-9;
const int inf = (1 << 30) - 1;
const int64 inf64 = ((int64)1 << 62) - 1;
const long double pi = 3.1415926535897932384626433832795;

template <class T> T sqr (T x) {return x * x;}
template <class T> T abs (T x) {return x < 0 ? -x : x;}

const int kmax = 21;
const int nmax = 1 << 17;

struct seg{
    int l, r, sum;

    seg () {
        init();
    };

    seg (int l, int r, int sum) : l(l), r(r), sum(sum) {};

    void set(int l1, int r1, int sum1) {
        l = l1;
        r = r1;
        sum = sum1;
    }

    void update(int l1, int r1, int sum1) {
        if (sum1 > sum)
            set(l1, r1, sum1);
    }

    void update(seg a) {
        if (a.sum > sum)
            set(a.l, a.r, a.sum);
    }

    void init() {
        l = 0; r = -1;
        sum = 0;
    }

    void write() {
        cerr << l << " " << r << " " << sum << endl;
    }
};

struct vertex {
    seg lft, rgt, al, sum;

    void init() {
        lft.init();
        rgt.init();
        al.init();
        sum.init();
    }

    vertex() {
        init();
    }

    vertex(int x, int l) {
        init();
        lft.update(l, l, x);
        rgt.update(l, l, x);
        sum.update(l, l, x);
        al.set(l, l, x);
    }

};

seg merge(seg a, seg b) {
    return seg(a.l, b.r, a.sum + b.sum);
}

vertex merge (const vertex &a, const vertex &b) {
    vertex res;
    res.al.set(a.al.l, b.al.r, a.al.sum + b.al.sum);

    res.lft = a.lft;
    res.lft.update(merge(a.al, b.lft));
    res.rgt = b.rgt;
    res.rgt.update(merge(a.rgt, b.al));

    res.sum = a.sum;
    res.sum.update(a.sum);
    res.sum.update(b.sum);
    res.sum.update(merge(a.rgt, b.lft));

    return res;
}

int n, m;
vertex t1[nmax*2], t2[nmax * 2];
vertex res;
int a[nmax];

void build (int v, int l, int r) {
    if (l > n) return;
    if (l == r) {
        t1[v] = vertex(a[l-1], l);
        t2[v] = vertex(-a[l-1], l);
        return;
    }
    int m = (l + r) / 2;
    build(v * 2, l, m);
    build(v * 2 + 1, m + 1, r);
    t1[v] = merge(t1[v * 2], t1[v*2 + 1]);
    t2[v] = merge(t2[v * 2], t2[v*2 + 1]);
}

void update(int v, int l, int r, int c, int x) {
    if (l > c || r < c) return;
    if (l == r) {
        t1[v] = vertex(x, l);
        t2[v] = vertex(-x, l);
        return;
    }
    int m = (l + r) / 2;
    update(v * 2, l, m, c, x);
    update(v * 2 + 1, m + 1, r, c, x);
    t1[v] = merge(t1[v * 2], t1[v*2 + 1]);
    t2[v] = merge(t2[v * 2], t2[v*2 + 1]);
}

vertex calcMax(int v, int l, int r, int l1, int r1) {
    if (l1 > r1) return vertex ();
    if (l1 > r || r1 < l) return vertex ();
    if (l1 <= l && r <= r1) return t1[v];
    int m = (l + r) / 2;
    return merge(calcMax(v * 2, l, m, l1, r1), calcMax(v * 2 + 1, m + 1, r, l1, r1));
}

vertex calcMin(int v, int l, int r, int l1, int r1) {
    if (l1 > r1) return vertex ();
    if (l1 > r || r1 < l) return vertex ();
    if (l1 <= l && r <= r1) return t2[v];
    int m = (l + r) / 2;
    return merge(calcMin(v * 2, l, m, l1, r1), calcMin(v * 2 + 1, m + 1, r, l1, r1));
}

int get(int l, int r, int k) {
    vector<int> a;
    a.pb(l-1);
    a.pb(r+1);
    int res = 0;
    forn(i, k) {
//      cerr << res << " " << k << endl;
        int bst = 0, pl, pr;
        pl = pr = -1;
        forn(j, a.size() - 1) {
            vertex now;
            if (j & 1)
                now = calcMin(1, 1, nmax, a[j], a[j+1]);
            else
                now = calcMax(1, 1, nmax, a[j] + 1, a[j+1] - 1);
            if (now.sum.sum > bst) {
//              cerr << " === "  << " " << (j & 1) << " " << a[j] << " " << a[j+1] << endl;
//              now.sum.write();
                bst = now.sum.sum;
                pl = now.sum.l;
                pr = now.sum.r;
            }
        }
//      cerr << bst << endl;
        if (bst == 0) break;
        a.pb(pl);
        a.pb(pr);
        sort(all(a));
        res += bst;
    }
    return res;
}

int main ()
{
//  freopen("input.txt", "rt", stdin);
//  freopen("out", "wt", stdout);

    cin >> n;
    forn(i, n)
        scanf("%d", &a[i]);
    build(1, 1, nmax);

    cin >> m;
    forn(i, m) {
        int x, l, r, k;
        scanf("%d %d %d", &x, &l, &r);
        if (x == 0) {
            update(1, 1, nmax, l, r);
            continue;
        } else {
            scanf("%d", &k);
            printf("%d\n", get(l, r, k));
        }
    }

//  cerr << clock() << endl;

    return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <ctime>
#include <cstring>
#include <cassert>
#include <bitset>
#include <sstream>
#include <queue>

using namespace std;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) int(a.size() - 1)
#define all(a) a.begin(), a.end()
#define seta(a,x) memset (a, x, sizeof (a))
#define I (int)

typedef long long int64;
typedef pair <int, int> pii;
typedef long double ldb;

const long double eps = 1e-9;
const int inf = (1 << 30) - 1;
const int64 inf64 = ((int64)1 << 62) - 1;
const long double pi = 3.1415926535897932384626433832795;

template <class T> T sqr (T x) {return x * x;}
template <class T> T abs (T x) {return x < 0 ? -x : x;}

const int kmax = 21;
const int nmax = 1 << 17;

struct seg{
    int l, r, sum;

    seg () {
        init();
    };

    seg (int l, int r, int sum) : l(l), r(r), sum(sum) {};

    void set(int l1, int r1, int sum1) {
        l = l1;
        r = r1;
        sum = sum1;
    }

    void update(int l1, int r1, int sum1) {
        if (sum1 > sum)
            set(l1, r1, sum1);
    }

    void update(seg a) {
        if (a.sum > sum)
            set(a.l, a.r, a.sum);
    }

    void init() {
        l = 0; r = -1;
        sum = 0;
    }

    void write() {
        cerr << l << " " << r << " " << sum << endl;
    }
};

struct vertex {
    seg lft, rgt, al, sum;

    void init() {
        lft.init();
        rgt.init();
        al.init();
        sum.init();
    }

    vertex() {
        init();
    }

    vertex(int x, int l) {
        init();
        lft.update(l, l, x);
        rgt.update(l, l, x);
        sum.update(l, l, x);
        al.set(l, l, x);
    }

};

seg merge(seg a, seg b) {
    return seg(a.l, b.r, a.sum + b.sum);
}

vertex merge (const vertex &a, const vertex &b) {
    vertex res;
    res.al.set(a.al.l, b.al.r, a.al.sum + b.al.sum);

    res.lft = a.lft;
    res.lft.update(merge(a.al, b.lft));
    res.rgt = b.rgt;
    res.rgt.update(merge(a.rgt, b.al));

    res.sum = a.sum;
    res.sum.update(a.sum);
    res.sum.update(b.sum);
    res.sum.update(merge(a.rgt, b.lft));

    return res;
}

int n, m;
vertex t1[nmax*2], t2[nmax * 2];
vertex res;
int a[nmax];

void build (int v, int l, int r) {
    if (l > n) return;
    if (l == r) {
        t1[v] = vertex(a[l-1], l);
        t2[v] = vertex(-a[l-1], l);
        return;
    }
    int m = (l + r) / 2;
    build(v * 2, l, m);
    build(v * 2 + 1, m + 1, r);
    t1[v] = merge(t1[v * 2], t1[v*2 + 1]);
    t2[v] = merge(t2[v * 2], t2[v*2 + 1]);
}

void update(int v, int l, int r, int c, int x) {
    if (l > c || r < c) return;
    if (l == r) {
        t1[v] = vertex(x, l);
        t2[v] = vertex(-x, l);
        return;
    }
    int m = (l + r) / 2;
    update(v * 2, l, m, c, x);
    update(v * 2 + 1, m + 1, r, c, x);
    t1[v] = merge(t1[v * 2], t1[v*2 + 1]);
    t2[v] = merge(t2[v * 2], t2[v*2 + 1]);
}

vertex calcMax(int v, int l, int r, int l1, int r1) {
    if (l1 > r1) return vertex ();
    if (l1 > r || r1 < l) return vertex ();
    if (l1 <= l && r <= r1) return t1[v];
    int m = (l + r) / 2;
    return merge(calcMax(v * 2, l, m, l1, r1), calcMax(v * 2 + 1, m + 1, r, l1, r1));
}

vertex calcMin(int v, int l, int r, int l1, int r1) {
    if (l1 > r1) return vertex ();
    if (l1 > r || r1 < l) return vertex ();
    if (l1 <= l && r <= r1) return t2[v];
    int m = (l + r) / 2;
    return merge(calcMin(v * 2, l, m, l1, r1), calcMin(v * 2 + 1, m + 1, r, l1, r1));
}

int get(int l, int r, int k) {
    vector<int> a;
    a.pb(l-1);
    a.pb(r+1);
    int res = 0;
    forn(i, k) {
//      cerr << res << " " << k << endl;
        int bst = 0, pl, pr;
        pl = pr = -1;
        forn(j, a.size() - 1) {
            vertex now;
            if (j & 1)
                now = calcMin(1, 1, nmax, a[j], a[j+1]);
            else
                now = calcMax(1, 1, nmax, a[j] + 1, a[j+1] - 1);
            if (now.sum.sum > bst) {
//              cerr << " === "  << " " << (j & 1) << " " << a[j] << " " << a[j+1] << endl;
//              now.sum.write();
                bst = now.sum.sum;
                pl = now.sum.l;
                pr = now.sum.r;
                if (j & 1) {
                    pl --; pr ++;
                }
            }
        }
//      cerr << bst << endl;
        if (bst == 0) break;
        a.pb(pl);
        a.pb(pr);
        sort(all(a));
        res += bst;
    }
    return res;
}

int main ()
{
//  freopen("input.txt", "rt", stdin);
//  freopen("out", "wt", stdout);

    cin >> n;
    forn(i, n)
        scanf("%d", &a[i]);
    build(1, 1, nmax);
//  cerr << clock() << endl;

    cin >> m;
    forn(i, m) {
        int x, l, r, k;
        scanf("%d %d %d", &x, &l, &r);
        if (x == 0) {
            update(1, 1, nmax, l, r);
            continue;
        } else {
            scanf("%d", &k);
            printf("%d\n", get(l, r, k));
        }
    }

//  cerr << clock() << endl;

    return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <ctime>
#include <cstring>
#include <cassert>
#include <bitset>
#include <sstream>
#include <queue>

using namespace std;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) int(a.size() - 1)
#define all(a) a.begin(), a.end()
#define seta(a,x) memset (a, x, sizeof (a))
#define I (int)

typedef long long int64;
typedef pair <int, int> pii;
typedef long double ldb;

const long double eps = 1e-9;
const int inf = (1 << 30) - 1;
const int64 inf64 = ((int64)1 << 62) - 1;
const long double pi = 3.1415926535897932384626433832795;

template <class T> T sqr (T x) {return x * x;}
template <class T> T abs (T x) {return x < 0 ? -x : x;}

const int kmax = 21;
const int nmax = 1 << 17;

struct vertex {
    int dp[kmax][2][2];

    void init() {
        forn(i, kmax)
            forn(j, 2)
                forn(k, 2)
                    dp[i][j][k] = -1e9;

        dp[0][0][0] = 0;
    }

    vertex() {
        init();
    }

    vertex(int x) {
        init();
        dp[1][1][1] = max(dp[1][1][1], x);
    }
};

void merge (vertex & res, vertex a, const vertex &b) {
    res.init();

    forn(f11, 2)
    forn(f22, 2) {
        forn(i, kmax)
        if (max(a.dp[i][f11][0], a.dp[i][f11][1]) > -1e9)
            for (int j = 0; i + j <= kmax; j ++) {
                if (i + j < kmax)
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], max(a.dp[i][f11][0] + max(b.dp[j][0][f22], b.dp[j][1][f22]),
                                                                    a.dp[i][f11][1] + b.dp[j][0][f22]));
                if (i > 0 && j > 0)
                    res.dp[i+j - 1][f11][f22] = max(res.dp[i+j-1][f11][f22], a.dp[i][f11][1] + b.dp[j][1][f22]);
            }
        forn(i, kmax)
            if (res.dp[i][f11][f22] < -1e8)
                res.dp[i][f11][f22] = -1e9;
    }

/*
    forn(i, kmax)
        forn(f11, 2)
            if (max(a.dp[i][f11][0], a.dp[i][f11][1]) > -1e9)
        for (int j = 0; i + j <= kmax; j ++)
        forn(f22, 2) {
            if (i + j < kmax) {
                res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][0] + b.dp[j][0][f22]);
                res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][0] + b.dp[j][1][f22]);
                res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][1] + b.dp[j][0][f22]);
            }
            if (i > 0 && j > 0)
                res.dp[i+j - 1][f11][f22] = max(res.dp[i+j-1][f11][f22], a.dp[i][f11][1] + b.dp[j][1][f22]);
        }

        */
    /*
    forn(i, kmax)
    forn(f11, 2)
        if (a.dp[i][f11][0] > -1e9)
            for (int j = 0; i + j <= kmax; j ++)
            forn(f22, 2) {
                if (i + j < kmax) {
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][0] + b.dp[j][0][f22]);
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][0] + b.dp[j][1][f22]);
                }
            }
    forn(i, kmax)
    forn(f11, 2)
        if (a.dp[i][f11][1] > -1e9)
            for (int j = 0; i + j <= kmax; j ++)
            forn(f22, 2) {
                if (i + j < kmax) {
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], a.dp[i][f11][1] + b.dp[j][0][f22]);
                }
                if (i > 0 && j > 0)
                    res.dp[i+j - 1][f11][f22] = max(res.dp[i+j-1][f11][f22], a.dp[i][f11][1] + b.dp[j][1][f22]);
            }   */
}

int n, m;
vertex t[nmax*2];
vertex res;
int a[nmax];

void update(int v, int l, int r, int c, int x) {
    if (c > r || c < l) return;
    if (l == r) {
        t[v] = vertex(x);
        return;
    }
    int m = (l + r) / 2;
    update(v * 2, l, m, c, x);
    update(v * 2 + 1, m + 1, r, c, x);
    merge(t[v], t[v*2], t[v*2 + 1]);
}

void build(int v, int l, int r, int n) {
    if (l > n) return;
    if (l == r) {
        t[v] = vertex(a[l-1]);
        return;
    }
    int m = (l + r) / 2;
    build(v * 2, l, m, n);
    build(v * 2 + 1, m + 1, r, n);
    merge(t[v], t[v*2], t[v*2 + 1]);
    //cerr << "34";
}

void get(int v, int l, int r, int l1, int r1) {
    if (l > r1 || r < l1) return;
    if (l1 <= l && r <= r1) {
        merge(res, res, t[v]);
        return;
    }
    int m = (l + r) / 2;
    get(v * 2, l, m, l1, r1);
    get(v * 2 + 1, m + 1, r, l1, r1);
}

int get(int l, int r, int k) {
    res.init();
    get(1, 1, nmax, l, r);
    int re = 0;
    forn(i, 2)
            forn(j, 2)
                re = max(re, res.dp[k][i][j]);
    return re;
}

int main ()
{
//  freopen("input.txt", "rt", stdin);
//  freopen("out", "wt", stdout);
    cin >> n;
    forn(i, n)
        scanf("%d", &a[i]);
//  cerr << clock() << endl;
    build(1, 1, nmax, n);
    cerr << clock() << endl;
//  return 0;
    cin >> m;
    forn(i, m) {
        int x, l, r, k;
        scanf("%d %d %d", &x, &l, &r);
        if (x == 0) {
            update(1, 1, nmax, l, r);
            continue;
        } else {
            scanf("%d", &k);
            printf("%d\n", get(l, r, k));
        }
    }

    cerr << clock() << endl;

    return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <ctime>
#include <cstring>
#include <cassert>
#include <bitset>
#include <sstream>
#include <queue>

using namespace std;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) int(a.size() - 1)
#define all(a) a.begin(), a.end()
#define seta(a,x) memset (a, x, sizeof (a))
#define I (int)

typedef long long int64;
typedef pair <int, int> pii;
typedef long double ldb;

const long double eps = 1e-9;
const int inf = (1 << 30) - 1;
const int64 inf64 = ((int64)1 << 62) - 1;
const long double pi = 3.1415926535897932384626433832795;

template <class T> T sqr (T x) {return x * x;}
template <class T> T abs (T x) {return x < 0 ? -x : x;}

const int kmax = 21;
const int nmax = 1 << 17;

struct vertex {
    int dp[kmax][2][2];

    void init() {
        forn(i, kmax)
            forn(j, 2)
                forn(k, 2)
                    dp[i][j][k] = -1e9;

        dp[0][0][0] = 0;
    }

    vertex() {
        init();
    }

    vertex(int x) {
        init();
        dp[1][1][1] = max(dp[1][1][1], x);
    }
};

void merge (vertex & res, vertex a, const vertex &b) {
    res.init();
    forn(f11, 2)
    forn(f22, 2) {
        forn(i, kmax) {
            if (i > 0 && a.dp[i-1][f11][0] >= a.dp[i][f11][0] && a.dp[i-1][f11][1] >= a.dp[i][f11][1]) break;
            if (max(a.dp[i][f11][0], a.dp[i][f11][1]) > -1e9)
            for (int j = 0; i + j <= kmax; j ++) {
                if (j > 0 && b.dp[j-1][0][f22] >= b.dp[j][0][f22] &&  b.dp[j-1][1][f22] >= b.dp[j][1][f22]) break;
                if (i + j < kmax)
                    res.dp[i+j][f11][f22] = max(res.dp[i+j][f11][f22], max(a.dp[i][f11][0] + max(b.dp[j][0][f22], b.dp[j][1][f22]),
                                                                    a.dp[i][f11][1] + b.dp[j][0][f22]));
                if (i > 0 && j > 0)
                    res.dp[i+j - 1][f11][f22] = max(res.dp[i+j-1][f11][f22], a.dp[i][f11][1] + b.dp[j][1][f22]);
            }
        }
        forn(i, kmax) {
            if (i > 0) res.dp[i][f11][f22] = max(res.dp[i][f11][f22], res.dp[i-1][f11][f22]);
            if (res.dp[i][f11][f22] < -1e8)
                res.dp[i][f11][f22] = -1e9;
        }
    }
}

int n, m;
vertex t[nmax*2];
vertex res;
int a[nmax];

void update(int v, int l, int r, int c, int x) {
    if (c > r || c < l) return;
    if (l == r) {
        t[v].dp[1][1][1] = x;
        return;
    }
    int m = (l + r) / 2;
    update(v * 2, l, m, c, x);
    update(v * 2 + 1, m + 1, r, c, x);
    merge(t[v], t[v*2], t[v*2 + 1]);
}

void build(int v, int l, int r, int n) {
    if (l > n) return;
    if (l == r) {
        t[v] = vertex(a[l-1]);
        return;
    }
    int m = (l + r) / 2;
    build(v * 2, l, m, n);
    build(v * 2 + 1, m + 1, r, n);
    merge(t[v], t[v*2], t[v*2 + 1]);
    //cerr << "34";
}

void get(int v, int l, int r, int l1, int r1) {
    if (l > r1 || r < l1) return;
    if (l1 <= l && r <= r1) {
        merge(res, res, t[v]);
        return;
    }
    int m = (l + r) / 2;
    get(v * 2, l, m, l1, r1);
    get(v * 2 + 1, m + 1, r, l1, r1);
}

int get(int l, int r, int k) {
    res.init();
    get(1, 1, nmax, l, r);
    int re = 0;
    forn(k1, k+1)
        forn(i, 2)
                forn(j, 2)
                re = max(re, res.dp[k1][i][j]);
    return re;
}

int main ()
{
//  freopen("input.txt", "rt", stdin);
//  freopen("out", "wt", stdout);

    cin >> n;
    forn(i, n)
        scanf("%d", &a[i]);
//  cerr << clock() << endl;
    build(1, 1, nmax, n);
    cerr << clock() << endl;
//  return 0;
    cin >> m;
    forn(i, m) {
        int x, l, r, k;
        scanf("%d %d %d", &x, &l, &r);
        if (x == 0) {
            update(1, 1, nmax, l, r);
            continue;
        } else {
            scanf("%d", &k);
            printf("%d\n", get(l, r, k));
        }
    }

    cerr << clock() << endl;

    return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define o 200001
using namespace std;
struct node{
	int l,r,s,sl,sr,sum,pl,pr;
	node(int pos=0,int ss=0){
		l=r=pl=pr=pos;
		s=sl=sr=sum=ss;
	}
};
//node operator + (node a,node b){return node(min(a.l,b.l),max(a.r,b.r),a.sum+b.sum);}
node merge(node a,node b){
	node c;
	c.sum=a.sum+b.sum;
	c.l=a.sl>a.sum+b.sl? a.l: b.l;
	c.sl=max(a.sl,a.sum+b.sl);
	c.r=b.sr>b.sum+a.sr? b.r: a.r;
	c.sr=max(b.sr,b.sum+a.sr);
	if(a.s>b.s) c.s=a.s,c.pl=a.pl,c.pr=a.pr;
	else c.s=b.s,c.pl=b.pl,c.pr=b.pr;
	if(c.s<a.sr+b.sl) c.s=a.sr+b.sl,c.pl=a.r,c.pr=b.l;
	return c;
}
struct P{
	int l,r;
	P(int ll=0,int rr=0){
		l=ll,r=rr;
	}
}stack[o];
struct Tree{
	node Max,Min;
	void Rever(){
		swap(Max,Min);
	}
	void get(int p,int value){
		Max=node(p,value);
		Min=node(p,-value);
	}
}T[o*4];
int n,m,a[o],li,ri,K,xi,ai,type;
bool rev[o*4];
void update(int now){
	T[now].Max=merge(T[now<<1].Max,T[now<<1|1].Max);
	T[now].Min=merge(T[now<<1].Min,T[now<<1|1].Min);
}
void pushdown(int now){
	if(!rev[now])return;
	rev[now<<1]^=1;rev[now<<1|1]^=1;
	T[now<<1].Rever();T[now<<1|1].Rever();
	rev[now]=0;
}
void change(int now,int l,int r,int pos,int value){
	if(l==r){
		T[now].get(l,value);
		return;
	}
	int mid=(l+r)>>1;
	pushdown(now);
	if(pos<=mid) change(now<<1,l,mid,pos,value);
	else change(now<<1|1,mid+1,r,pos,value);
	update(now);
}
void Rev(int now,int l,int r,int left,int right){
	if(left<=l&&r<=right){
		rev[now]^=1;
		T[now].Rever();
		return;
	}
	int mid=(l+r)>>1;
	pushdown(now);
	if(left<=mid) Rev(now<<1,l,mid,left,right);
	if(mid<right) Rev(now<<1|1,mid+1,r,left,right);
	update(now);
}
node query(int now,int l,int r,int left,int right){
	if(left<=l&&r<=right) return T[now].Max;
	int mid=(l+r)>>1;
	pushdown(now);
	if(left<=mid&&mid<right)
		return merge(query(now<<1,l,mid,left,right),query(now<<1|1,mid+1,r,left,right));
	else{
		if(left<=mid) return query(now<<1,l,mid,left,right);
		if(mid<right) return query(now<<1|1,mid+1,r,left,right);
	}
}
void build(int now,int l,int r){
	if(l==r){
		T[now].get(l,a[l]);
		return;
	}
	int mid=(l+r)>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	update(now);
}
inline void in(int &ans, char ch = getchar(), bool flag = false)
{
    ans = 0;
    for (; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
    if (ch == '-')
    {
        ch = getchar();
        flag = true;
    }
    for (; ch >= '0' && ch <= '9'; ans = (ans << 3) + (ans << 1) + ch - 48, ch = getchar());
    if (flag) ans = -ans;
}
int main(){
	in(n);
	for(int i=1;i<=n;i++) in(a[i]);
	build(1,1,n);
	in(m);
	for(int i=1;i<=m;i++){
		in(type);
		if(type==0){
			in(xi),in(ai);
			change(1,1,n,xi,ai);
		}
		else{
			in(li),in(ri),in(K);
			long long sum=0;
			int l,r,size=0;
			node now;
			for(int i=1;i<=K;i++){
				now=query(1,1,n,li,ri);
				if(now.s<=0)break;
				sum+=now.s;
				Rev(1,1,n,now.pl,now.pr);
				stack[++size]=P(now.pl,now.pr);
			}
			for(int i=size;i;i--) Rev(1,1,n,stack[i].l,stack[i].r);
			printf("%lld\n",sum);
		}
	}
	return 0;
}


#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
#define ll long long
#define ls (p<<1)
#define rs ((p<<1)|1)
#define size(p) ((tr[p].r)-(tr[p].l)+(1))
#define leaf(p) (tr[p].l==tr[p].r)
#define cntn(p) ((l==x)&&(y==r))
const int MAXN=100000+20;
int n,m;

struct data
{
    //左段和，右段和，子段最大和，总和
    int lx,rx,mx,sum;
    //左段和右端点，右段和左端点，最大和左端点，最大和右端点
    int lp,rp,p1,p2;
    void init(int x,int val)
    {
        lp=rp=p1=p2=x;
        lx=rx=mx=sum=val;
    }
};
struct seg
{
    int l,r,rev;
    data mn,mx;
    void init(int val)
    {
        mx.init(l,val);
        mn.init(l,-val);//////////////
    }
}tr[MAXN*4];

void dwn(int p)
{
    if(leaf(p)||!tr[p].rev)return ;
    swap(tr[ls].mn,tr[ls].mx);
    swap(tr[rs].mn,tr[rs].mx);
    tr[p].rev^=1;tr[ls].rev^=1;tr[rs].rev^=1;
}

data merge(data a,data b)
{
    data t;
    t.sum=a.sum+b.sum;

    t.lx=a.lx,t.lp=a.lp;
    t.rx=b.rx,t.rp=b.rp;
    if(t.lx<a.sum+b.lx)t.lx=a.sum+b.lx,t.lp=b.lp;
    if(t.rx<b.sum+a.rx)t.rx=b.sum+a.rx,t.rp=a.rp;
    //////////这一段不用再像上面一样算固定左/右端点的左缀/右缀，直接用儿子做好的，包括了上述情况;
    t.mx=a.rx+b.lx;t.p1=a.rp,t.p2=b.lp;
    if(t.mx<a.mx)t.mx=a.mx,t.p1=a.p1,t.p2=a.p2;
    if(t.mx<b.mx)t.mx=b.mx,t.p1=b.p1,t.p2=b.p2;

    return t;
}
void upp(int p)
{
    tr[p].mn=merge(tr[ls].mn,tr[rs].mn);
    tr[p].mx=merge(tr[ls].mx,tr[rs].mx);
}
void build(int p,int l,int r)
{
    tr[p].l=l;tr[p].r=r;
    if(leaf(p))
    {
        int val;
        scanf("%d",&val);
        tr[p].init(val);
        return ;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    upp(p);
}
void ins(int p,int x,int val)
{
    dwn(p);
    int l=tr[p].l,r=tr[p].r;
    if(leaf(p))
    {
        tr[p].init(val);
        return ;
    }
    int mid=(l+r)>>1;
    if(x<=mid)ins(ls,x,val);
    else if(mid<x)ins(rs,x,val);
    upp(p);
}
void revers(int p,int x,int y)
{
    dwn(p);
    int l=tr[p].l,r=tr[p].r;
    if(cntn(p))
    {
        swap(tr[p].mn,tr[p].mx);
        tr[p].rev^=1;
        return ;
    }
    int mid=(l+r)>>1;
    if(y<=mid)revers(ls,x,y);
    else if(mid<x)revers(rs,x,y);
    else revers(ls,x,mid),revers(rs,mid+1,y);
    upp(p);

}
data qry(int p,int x,int y)
{
    dwn(p);
    int l=tr[p].l,r=tr[p].r;
    if(cntn(p))return tr[p].mx;
    int mid=(l+r)>>1;
    if(y<=mid)return qry(ls,x,y);
    else if(mid<x)return qry(rs,x,y);
    else return merge(qry(ls,x,mid),qry(rs,mid+1,y));
}

void solve(int l,int r,int k)
{
    int ans=0;
    stack<int>sc1,sc2;
    while(k--)
    {
        data t=qry(1,l,r);
        if(t.mx>0)ans+=t.mx;
        else break;
        revers(1,t.p1,t.p2);
        sc1.push(t.p1);sc2.push(t.p2);
    }
    while(!sc1.empty())
    {
        revers(1,sc1.top(),sc2.top());
        sc1.pop();sc2.pop();
    }
    printf("%d\n",ans);
}
int main()
{
    scanf("%d",&n);build(1,1,n);
    scanf("%d",&m);int op,x,y,z;
    while(m--)
    {
        scanf("%d%d%d",&op,&x,&y);
        if(op==0)ins(1,x,y);
        else if(op==1)
        {
            scanf("%d",&z);
            solve(x,y,z);
        }
    }
    return 0;
}


#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
#define ll long long
#define ls (p<<1)
#define rs ((p<<1)|1)
#define size(p) ((tr[p].r)-(tr[p].l)+(1))
#define leaf(p) (tr[p].l==tr[p].r)
#define cntn(p) ((l==x)&&(y==r))
const int MAXN=100000+20;
int n,m;

struct data
{
	//左段和，右段和，子段最大和，总和
	int lx,rx,mx,sum;
	//左段和右端点，右段和左端点，最大和左端点，最大和右端点
	int lp,rp,p1,p2;
	void init(int x,int val)
	{
		lp=rp=p1=p2=x;
		lx=rx=mx=sum=val;
	}
};
struct seg
{
	int l,r,rev;
	data mn,mx;
	void init(int val)
	{
		mx.init(l,val);
		mn.init(l,-val);//////////////
	}
}tr[MAXN*4];

void dwn(int p)
{
	if(leaf(p)||!tr[p].rev)return ;
	swap(tr[ls].mn,tr[ls].mx);
	swap(tr[rs].mn,tr[rs].mx);
	tr[p].rev^=1;tr[ls].rev^=1;tr[rs].rev^=1;
}

data merge(data a,data b)
{
	data t;
	t.sum=a.sum+b.sum;

	t.lx=a.lx,t.lp=a.lp;
	t.rx=b.rx,t.rp=b.rp;
	if(t.lx<a.sum+b.lx)t.lx=a.sum+b.lx,t.lp=b.lp;
	if(t.rx<b.sum+a.rx)t.rx=b.sum+a.rx,t.rp=a.rp;
	//////////这一段不用再像上面一样算固定左/右端点的左缀/右缀，直接用儿子做好的，包括了上述情况;
	t.mx=a.rx+b.lx;t.p1=a.rp,t.p2=b.lp;
	if(t.mx<a.mx)t.mx=a.mx,t.p1=a.p1,t.p2=a.p2;
	if(t.mx<b.mx)t.mx=b.mx,t.p1=b.p1,t.p2=b.p2;

	return t;
}
void upp(int p)
{
	tr[p].mn=merge(tr[ls].mn,tr[rs].mn);
	tr[p].mx=merge(tr[ls].mx,tr[rs].mx);
}
void build(int p,int l,int r)
{
	tr[p].l=l;tr[p].r=r;
	if(leaf(p))
	{
		int val;
		scanf("%d",&val);
		tr[p].init(val);
		return ;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	upp(p);
}
void ins(int p,int x,int val)
{
	dwn(p);
	int l=tr[p].l,r=tr[p].r;
	if(leaf(p))
	{
		tr[p].init(val);
		return ;
	}
	int mid=(l+r)>>1;
	if(x<=mid)ins(ls,x,val);
	else if(mid<x)ins(rs,x,val);
	upp(p);
}
void revers(int p,int x,int y)
{
	dwn(p);
	int l=tr[p].l,r=tr[p].r;
	if(cntn(p))
	{
		swap(tr[p].mn,tr[p].mx);
		tr[p].rev^=1;
		return ;
	}
	int mid=(l+r)>>1;
	if(y<=mid)revers(ls,x,y);
	else if(mid<x)revers(rs,x,y);
	else revers(ls,x,mid),revers(rs,mid+1,y);
	upp(p);

}
data qry(int p,int x,int y)
{
	dwn(p);
	int l=tr[p].l,r=tr[p].r;
	if(cntn(p))return tr[p].mx;
	int mid=(l+r)>>1;
	if(y<=mid)return qry(ls,x,y);
	else if(mid<x)return qry(rs,x,y);
	else return merge(qry(ls,x,mid),qry(rs,mid+1,y));
}

void solve(int l,int r,int k)
{
	int ans=0;
	stack<int>sc1,sc2;
	while(k--)
	{
		data t=qry(1,l,r);
		if(t.mx>0)ans+=t.mx;
		else break;
		revers(1,t.p1,t.p2);
		sc1.push(t.p1);sc2.push(t.p2);
	}
	while(!sc1.empty())
	{
		revers(1,sc1.top(),sc2.top());
		sc1.pop();sc2.pop();
	}
	printf("%d\n",ans);
}
int main()
{
	scanf("%d",&n);build(1,1,n);
	scanf("%d",&m);int op,x,y,z;
	while(m--)
	{
		scanf("%d%d%d",&op,&x,&y);
		if(op==0)ins(1,x,y);
		else if(op==1)
		{
			scanf("%d",&z);
			solve(x,y,z);
		}
	}
	return 0;
}


#include <iostream>
#include <string.h>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <limits.h>
#include <vector>
#include <string>
using namespace         std;
const int               Maxn=400010;
struct F{
    int x,y,sum;
};
struct Tree{
    F lmin,rmin,smin;
    F lmax,rmax,smax;
    F all;
    int mk;

}                       t[Maxn];
int                     n,m,i,j,op,l,r,k,ans;
vector<F>               opr;

F max(F a,F b)
{
    if (a.sum>b.sum) return a; return b;
}

F min(F a,F b)
{
    if (a.sum<b.sum) return a; return b;
}

Tree New(int l,int key)
{
    Tree t;
    t.lmin=t.rmin=t.smin=(F){l,l,key};
    t.lmax=t.rmax=t.smax=(F){l,l,key};
    t.all=(F){l,l,key};
    t.mk=0;
    return t;
}
F operator +(F a, F b)
{
    if (a.x==-1) return b;
    if (b.x==-1) return a;
    return (F){a.x,b.y,a.sum+b.sum};
}
Tree operator +(Tree a,Tree b)
{
    Tree c;
    c.lmin=min(a.lmin,a.all+b.lmin);
    c.rmin=min(b.rmin,a.rmin+b.all);
    c.smin=min(min(a.smin,b.smin),a.rmin+b.lmin);
    c.lmax=max(a.lmax,a.all+b.lmax);
    c.rmax=max(b.rmax,a.rmax+b.all);
    c.smax=max(max(a.smax,b.smax),a.rmax+b.lmax);
    c.all=a.all+b.all;
    c.mk=0;
    return c;
}

void exc(F &a,F &b)
{
    swap(a,b);
    a.sum*=-1; b.sum*=-1;
}

void check(int k,int l,int r)
{
    if (!t[k].mk) return;
    exc(t[k].lmin,t[k].lmax);
    exc(t[k].rmin,t[k].rmax);
    exc(t[k].smin,t[k].smax);
    t[k].all.sum*=-1;
    t[k].mk=0;
    if (r-l)
    {
        t[k*2].mk=(t[k*2].mk+1)%2;
        t[k*2+1].mk=(t[k*2+1].mk+1)%2;
    }
}
void ins(int k,int l,int r,int x,int y,int key)
{
    check(k,l,r);
    if(r<x||y<l) return;
    if(x<=l&&r<=y)
    {
        t[k]=New(l,key);
        return;
    }
    int mid=(l+r)/2;
    ins(k*2,l,mid,x,y,key);
    ins(k*2+1,mid+1,r,x,y,key);
    t[k]=t[k*2]+t[k*2+1];
}
Tree get(int k,int l,int r,int x,int y)
{
    check(k,l,r);
    if(r<x||y<l) return New(-1,0);
    if(x<=l&&r<=y)
        return t[k];
    int mid=(l+r)/2;
    return get(k*2,l,mid,x,y)+get(k*2+1,mid+1,r,x,y);
}
void Rev(int k,int l,int r,int x,int y)
{
    check(k,l,r);
    if(r<x||y<l) return ;
    if(x<=l&&r<=y)
    {
        t[k].mk=(t[k].mk+1)%2;
        check(k,l,r);
        return;
    }
    int mid=(l+r)/2;
    Rev(k*2,l,mid,x,y);
    Rev(k*2+1,mid+1,r,x,y);
    t[k]=t[k*2]+t[k*2+1];
}
int main()
{
    ios::sync_with_stdio(0);
    //freopen("/Users/MAC/Desktop/Error202/Error202/1.in","r",stdin);
    //freopen("/Users/MAC/Desktop/Error202/Error202/1.out","w",stdout);
    cin>>n;
    for (i=1;i<=n;i++)
    {
        cin>>m;
        ins(1,1,n,i,i,m);
    }
    cin>>m;
    for(i=1;i<=m;i++)
    {
        cin>>op;
        if (op)
        {
            cin>>l>>r>>k;
            opr.clear();
            ans=0;
            for (j=1;j<=k;j++)
            {
                F cag=get(1,1,n,l,r).smax;
                if(cag.sum<=0) break;
                ans+=cag.sum;
                opr.push_back(cag);
                Rev(1,1,n,cag.x,cag.y);
            }
            for (j=0;j<opr.size();j++)
                Rev(1,1,n,opr[j].x,opr[j].y);
            cout<<ans<<endl;
        }
        else
        {
            cin>>l>>k;
            ins(1,1,n,l,l,k);
        }
    }
}


#include <iostream>
#include <string.h>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <limits.h>
#include <vector>
#include <string>
using namespace         std;
const int               Maxn=100010;
struct F{
    int x,y,sum;
};
struct Tree{
    F lmin,rmin,smin;
    F lmax,rmax,smax;
    F all;
    int mk;

}                       t[Maxn];
int                     n,m,i,j,op,l,r,k,ans;
vector<F>               opr;

F max(F a,F b)
{
    if (a.sum>b.sum) return a; return b;
}

F min(F a,F b)
{
    if (a.sum<b.sum) return a; return b;
}

Tree New(int l,int key)
{
    Tree t;
    t.lmin=t.rmin=t.smin=(F){l,l,key};
    t.lmax=t.rmax=t.smax=(F){l,l,key};
    t.all=(F){l,l,key};
    t.mk=0;
    return t;
}
F operator +(F a, F b)
{
    if (a.x==-1) return b;
    if (b.x==-1) return a;
    return (F){a.x,b.y,a.sum+b.sum};
}
Tree operator +(Tree a,Tree b)
{
    Tree c;
    c.lmin=min(a.lmin,a.all+b.lmin);
    c.rmin=min(b.rmin,a.rmin+b.all);
    c.smin=min(min(a.smin,b.smin),a.rmin+b.lmin);
    c.lmax=max(a.lmax,a.all+b.lmax);
    c.rmax=max(b.rmax,a.rmax+b.all);
    c.smax=max(max(a.smax,b.smax),a.rmax+b.lmax);
    c.all=a.all+b.all;
    c.mk=0;
    return c;
}
void down(int k,int l,int r)
{
    if (l>r) return;
    t[k].mk*=-1;
}
void exc(F &a,F &b)
{
    swap(a,b);
    a.sum*=-1; b.sum*=-1;
}

void check(int k,int l,int r)
{
    if (!t[k].mk) return;
    exc(t[k].lmin,t[k].lmax);
    exc(t[k].rmin,t[k].rmax);
    exc(t[k].smin,t[k].smax);
    t[k].all.sum*=-1;
    t[k].mk=0;
    int mid=(l+r)/2;
    down(k*2,l,mid);
    down(k*2+1,mid+1,r);
}
void ins(int k,int l,int r,int x,int y,int key)
{
    check(k,l,r);
    if(r<x||y<l) return;
    if(x<=l&&r<=y)
    {
        t[k]=New(l,key);
        return;
    }
    int mid=(l+r)/2;
    ins(k*2,l,mid,x,y,key);
    ins(k*2+1,mid+1,r,x,y,key);
    t[k]=t[k*2]+t[k*2+1];
}
Tree get(int k,int l,int r,int x,int y)
{
    check(k,l,r);
    if(r<x||y<l) return New(-1,0);
    if(x<=l&&r<=y)
        return t[k];
    int mid=(l+r)/2;
    return get(k*2,l,mid,x,y)+get(k*2+1,mid+1,r,x,y);
}
void Rev(int k,int l,int r,int x,int y)
{
    check(k,l,r);
    if(r<x||y<l) return ;
    if(x<=l&&r<=y)
    {
        t[k].mk=(t[k].mk+1)%2;
        check(k,l,r);
        return;
    }
    int mid=(l+r)/2;
    Rev(k*2,l,mid,x,y);
    Rev(k*2+1,mid+1,r,x,y);
    t[k]=t[k*2]+t[k*2+1];
}
int main()
{
    ios::sync_with_stdio(0);
    //freopen("/Users/MAC/Desktop/Error202/Error202/1.in","r",stdin);
    //freopen("/Users/MAC/Desktop/Error202/Error202/1.out","w",stdout);
    cin>>n;
    for (i=1;i<=n;i++)
    {
        cin>>m;
        ins(1,1,n,i,i,m);
    }
    cin>>m;
    for(i=1;i<=m;i++)
    {
        cin>>op;
        if (op)
        {
            cin>>l>>r>>k;
            opr.clear();
            ans=0;
            for (j=1;j<=k;j++)
            {
                F cag=get(1,1,n,l,r).smax;
                if(cag.sum<=0) break;
                ans+=cag.sum;
                opr.push_back(cag);
                Rev(1,1,n,cag.x,cag.y);
            }
            for (j=0;j<opr.size();j++)
                Rev(1,1,n,opr[j].x,opr[j].y);
            cout<<ans<<endl;
        }
        else
        {
            cin>>l>>k;
            ins(1,1,n,l,l,k);
        }
    }
}


#include <iostream>
#include <string.h>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <limits.h>
#include <vector>
#include <string>
using namespace         std;
const int               Maxn=400010;
struct F{
    int x,y,sum;
};
struct Tree{
    F lmin,rmin,smin;
    F lmax,rmax,smax;
    F all;
    int mk;

}                       t[Maxn];
int                     n,m,i,j,op,l,r,k,ans;
vector<F>               opr;

F max(F a,F b)
{
    if (a.sum>b.sum) return a; return b;
}

F min(F a,F b)
{
    if (a.sum<b.sum) return a; return b;
}

Tree New(int l,int key)
{
    Tree t;
    t.lmin=t.rmin=t.smin=(F){l,l,key};
    t.lmax=t.rmax=t.smax=(F){l,l,key};
    t.all=(F){l,l,key};
    t.mk=0;
    return t;
}
F operator +(F a, F b)
{
    if (a.x==-1) return b;
    if (b.x==-1) return a;
    return (F){a.x,b.y,a.sum+b.sum};
}
Tree operator +(Tree a,Tree b)
{
    Tree c;
    c.lmin=min(a.lmin,a.all+b.lmin);
    c.rmin=min(b.rmin,a.rmin+b.all);
    c.smin=min(min(a.smin,b.smin),a.rmin+b.lmin);
    c.lmax=max(a.lmax,a.all+b.lmax);
    c.rmax=max(b.rmax,a.rmax+b.all);
    c.smax=max(max(a.smax,b.smax),a.rmax+b.lmax);
    c.all=a.all+b.all;
    c.mk=0;
    return c;
}

void exc(F &a,F &b)
{
    swap(a,b);
    a.sum*=-1; b.sum*=-1;
}

void check(int k,int l,int r)
{
    if (!t[k].mk) return;
    exc(t[k].lmin,t[k].lmax);
    exc(t[k].rmin,t[k].rmax);
    exc(t[k].smin,t[k].smax);
    t[k].all.sum*=-1;
    t[k].mk=0;
    if (r-l)
    {
        t[k*2].mk=(t[k*2].mk+1)%2;
        t[k*2+1].mk=(t[k*2+1].mk+1)%2;
    }
}
void ins(int k,int l,int r,int x,int y,int key)
{
    check(k,l,r);
    if(r<x||y<l) return;
    if(x<=l&&r<=y)
    {
        t[k]=New(l,key);
        return;
    }
    int mid=(l+r)/2;
    ins(k*2,l,mid,x,y,key);
    ins(k*2+1,mid+1,r,x,y,key);
    t[k]=t[k*2]+t[k*2+1];
}
Tree get(int k,int l,int r,int x,int y)
{
    check(k,l,r);
    if(r<x||y<l) return New(-1,0);
    if(x<=l&&r<=y)
        return t[k];
    int mid=(l+r)/2;
    return get(k*2,l,mid,x,y)+get(k*2+1,mid+1,r,x,y);
}
void Rev(int k,int l,int r,int x,int y)
{
    check(k,l,r);
    if(r<x||y<l) return ;
    if(x<=l&&r<=y)
    {
        t[k].mk=(t[k].mk+1)%2;
        check(k,l,r);
        return;
    }
    int mid=(l+r)/2;
    Rev(k*2,l,mid,x,y);
    Rev(k*2+1,mid+1,r,x,y);
    t[k]=t[k*2]+t[k*2+1];
}
int main()
{
    ios::sync_with_stdio(0);
    freopen("/Users/MAC/Desktop/Error202/Error202/1.in","r",stdin);
    //freopen("/Users/MAC/Desktop/Error202/Error202/1.out","w",stdout);
    cin>>n;
    for (i=1;i<=n;i++)
    {
        cin>>m;
        ins(1,1,n,i,i,m);
    }
    cin>>m;
    for(i=1;i<=m;i++)
    {
        cin>>op;
        if (op)
        {
            cin>>l>>r>>k;
            opr.clear();
            ans=0;
            for (j=1;j<=k;j++)
            {
                F cag=get(1,1,n,l,r).smax;
                if(cag.sum<=0) break;
                ans+=cag.sum;
                opr.push_back(cag);
                Rev(1,1,n,cag.x,cag.y);
            }
            for (j=0;j<opr.size();j++)
                Rev(1,1,n,opr[j].x,opr[j].y);
            cout<<ans<<endl;
        }
        else
        {
            cin>>l>>k;
            ins(1,1,n,l,l,k);
        }
    }
}


#include <iostream>
#include <string.h>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <limits.h>
#include <vector>
#include <string>
using namespace         std;
const int               Maxn=100010;
struct F{
    int x,y,sum;
};
struct Tree{
    F lmin,rmin,smin;
    F lmax,rmax,smax;
    F all;
    int mk;

}                       t[Maxn];
int                     n,m,i,j,op,l,r,k,ans;
vector<F>               opr;

F max(F a,F b)
{
    if (a.sum>b.sum) return a; return b;
}

F min(F a,F b)
{
    if (a.sum<b.sum) return a; return b;
}

Tree New(int l,int key)
{
    Tree t;
    t.lmin=t.rmin=t.smin=(F){l,l,key};
    t.lmax=t.rmax=t.smax=(F){l,l,key};
    t.all=(F){l,l,key};
    t.mk=0;
    return t;
}
F operator +(F a, F b)
{
    if (a.x==-1) return b;
    if (b.x==-1) return a;
    return (F){a.x,b.y,a.sum+b.sum};
}
Tree operator +(Tree a,Tree b)
{
    Tree c;
    c.lmin=min(a.lmin,a.all+b.lmin);
    c.rmin=min(b.rmin,a.rmin+b.all);
    c.smin=min(min(a.smin,b.smin),a.rmin+b.lmin);
    c.lmax=max(a.lmax,a.all+b.lmax);
    c.rmax=max(b.rmax,a.rmax+b.all);
    c.smax=max(max(a.smax,b.smax),a.rmax+b.lmax);
    c.all=a.all+b.all;
    c.mk=0;
    return c;
}

void exc(F &a,F &b)
{
    swap(a,b);
    a.sum*=-1; b.sum*=-1;
}

void check(int k,int l,int r)
{
    if (!t[k].mk) return;
    exc(t[k].lmin,t[k].lmax);
    exc(t[k].rmin,t[k].rmax);
    exc(t[k].smin,t[k].smax);
    t[k].all.sum*=-1;
    t[k].mk=0;
    if (r-l)
    {
        t[k*2].mk=(t[k*2].mk+1)%2;
        t[k*2+1].mk=(t[k*2+1].mk+1)%2;
    }
}
void ins(int k,int l,int r,int x,int y,int key)
{
    check(k,l,r);
    if(r<x||y<l) return;
    if(x<=l&&r<=y)
    {
        t[k]=New(l,key);
        return;
    }
    int mid=(l+r)/2;
    ins(k*2,l,mid,x,y,key);
    ins(k*2+1,mid+1,r,x,y,key);
    t[k]=t[k*2]+t[k*2+1];
}
Tree get(int k,int l,int r,int x,int y)
{
    check(k,l,r);
    if(r<x||y<l) return New(-1,0);
    if(x<=l&&r<=y)
        return t[k];
    int mid=(l+r)/2;
    return get(k*2,l,mid,x,y)+get(k*2+1,mid+1,r,x,y);
}
void Rev(int k,int l,int r,int x,int y)
{
    check(k,l,r);
    if(r<x||y<l) return ;
    if(x<=l&&r<=y)
    {
        t[k].mk=(t[k].mk+1)%2;
        check(k,l,r);
        return;
    }
    int mid=(l+r)/2;
    Rev(k*2,l,mid,x,y);
    Rev(k*2+1,mid+1,r,x,y);
    t[k]=t[k*2]+t[k*2+1];
}
int main()
{
    ios::sync_with_stdio(0);
    //freopen("/Users/MAC/Desktop/Error202/Error202/1.in","r",stdin);
    //freopen("/Users/MAC/Desktop/Error202/Error202/1.out","w",stdout);
    cin>>n;
    for (i=1;i<=n;i++)
    {
        cin>>m;
        ins(1,1,n,i,i,m);
    }
    cin>>m;
    for(i=1;i<=m;i++)
    {
        cin>>op;
        if (op)
        {
            cin>>l>>r>>k;
            opr.clear();
            ans=0;
            for (j=1;j<=k;j++)
            {
                F cag=get(1,1,n,l,r).smax;
                if(cag.sum<=0) break;
                ans+=cag.sum;
                opr.push_back(cag);
                Rev(1,1,n,cag.x,cag.y);
            }
            for (j=0;j<opr.size();j++)
                Rev(1,1,n,opr[j].x,opr[j].y);
            cout<<ans<<endl;
        }
        else
        {
            cin>>l>>k;
            ins(1,1,n,l,l,k);
        }
    }
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <bitset>
#include <cmath>
#include <ctime>
#include <cassert>
using namespace std;

#define pb push_back
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (n); i++)
#define foreach(e, x) for (__typeof(x.begin()) e = x.begin(); e != x.end(); e++)
#define FAST_IO std::ios::sync_with_stdio(false)
typedef long long LL;
typedef pair<int, int> PII;
int rd() { return RAND_MAX == 32767 ? ((rand() << 15) ^ rand()) : rand(); }

const int maxn = 100010;

int a[maxn];

struct Segment
{
	int l, r, sum;

	Segment() {}
	Segment(int l_, int r_, int sum_) : l(l_), r(r_), sum(sum_) {}
	Segment operator + (const Segment &o) const
	{
		Segment res;
		res.sum = sum+o.sum;
		res.l = l;
		res.r = o.r;
		return res;
	}
	bool operator < (const Segment &o) const
	{
		return sum < o.sum;
	}
} cntR, cntS;
struct Tree
{
	int l, r, chg;
	Segment sum, maxL, maxR, maxS, minL, minR, minS;
	Tree *lc, *rc;

	void setNode(int val)
	{
		sum = Segment(l, r, val);
		if (val > 0) maxL = maxR = maxS = Segment(l, r, val);
		else {
			maxL = maxS = Segment(l, l, 0);
			maxR = Segment(r, r, 0);
		}
		if (val < 0) minL = minR = minS = Segment(l, r, val);
		else {
			minL = minS = Segment(l, l, 0);
			minR = Segment(r, r, 0);
		}
	}
	Tree(int l_, int r_) : l(l_), r(r_)
	{
		lc = l+1 < r ? new Tree(l, (l+r) >> 1) : NULL;
		rc = l+1 < r ? new Tree((l+r) >> 1, r) : NULL;
		chg = 0;
		if (l+1 < r) fresh();
		else setNode(a[l]);
	}
	void fresh()
	{
		maxS = max(max(lc->maxS, rc->maxS), lc->maxR+rc->maxL);
		maxL = max(lc->maxL, lc->sum+rc->maxL);
		maxR = max(rc->maxR, lc->maxR+rc->sum);
		minS = min(min(lc->minS, rc->minS), lc->minR+rc->minL);
		minL = min(lc->minL, lc->sum+rc->minL);
		minR = min(rc->minR, lc->minR+rc->sum);
		sum = lc->sum+rc->sum;
	}
	void modify()
	{
		chg ^= 1;
		swap(minL, maxL);
		swap(minR, maxR);
		swap(minS, maxS);
		maxL.sum = -maxL.sum;
		maxR.sum = -maxR.sum;
		maxS.sum = -maxS.sum;
		minL.sum = -minL.sum;
		minR.sum = -minR.sum;
		minS.sum = -minS.sum;
		sum.sum = -sum.sum;
	}
	void down()
	{
		chg = 0;
		lc->modify();
		rc->modify();
	}
	void change(int x, int y)
	{
		if (l+1 == r) setNode(y);
		else {
			if (chg) down();
			x < (l+r) >> 1 ? lc->change(x, y) : rc->change(x, y);
			fresh();
		}
	}
	void query(int ll, int rr)
	{
		if (ll <= l && rr >= r) {
			cntS = max(max(cntS, maxS), cntR+maxL);
			cntR = max(maxR, cntR+sum);
		}
		else {
			if (chg) down();
			if (ll < (l+r) >> 1) lc->query(ll, rr);
			if (rr > (l+r) >> 1) rc->query(ll, rr);
			fresh();
		}
	}
	void negative(int ll, int rr)
	{
		if (ll <= l && rr >= r) modify();
		else {
			if (chg) down();
			if (ll < (l+r) >> 1) lc->negative(ll, rr);
			if (rr > (l+r) >> 1) rc->negative(ll, rr);
			fresh();
		}
	}
} *root;
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n, m;
	cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i];
	root = new Tree(0, n);
	cin >> m;
	for (int i = 0; i < m; i++) {
		int opt;
		cin >> opt;
		if (opt == 0) {
			int pos, val;
			cin >> pos >> val; pos--;
			root->change(pos, val);
		}
		else {
			int l, r, k, res = 0;
			cin >> l >> r >> k; l--;
			vector<PII> b;
			for (int i = 0; i < k; i++) {
				cntS = cntR = Segment(l, l, 0);
				root->query(l, r);
				res += cntS.sum;
				if (cntS.l < cntS.r) {
					root->negative(cntS.l, cntS.r);
					b.pb(mp(cntS.l, cntS.r));
				}
				else break;
			}
			for (int i = 0; i < b.size(); i++)
				root->negative(b[i].first, b[i].second);
			cout << res << endl;
		}
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <bitset>
#include <cmath>
#include <ctime>
#include <cassert>
using namespace std;

#define pb push_back
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (n); i++)
#define foreach(e, x) for (__typeof(x.begin()) e = x.begin(); e != x.end(); e++)
#define FAST_IO std::ios::sync_with_stdio(false)
typedef long long LL;
typedef pair<int, int> PII;
int rd() { return RAND_MAX == 32767 ? ((rand() << 15) ^ rand()) : rand(); }

const int maxn = 100010;

int a[maxn];

struct Segment
{
	int l, r, sum;

	Segment() {}
	Segment(int l_, int r_, int sum_) : l(l_), r(r_), sum(sum_) {}
	Segment operator + (const Segment &o) const
	{
		Segment res;
		res.sum = sum+o.sum;
		res.l = l;
		res.r = o.r;
		return res;
	}
	bool operator < (const Segment &o) const
	{
		return sum < o.sum;
	}
} cntR, cntS;
struct Tree
{
	int l, r, chg;
	Segment sum, maxL, maxR, maxS, minL, minR, minS;
	Tree *lc, *rc;

	void setNode(int val)
	{
		sum = Segment(l, r, val);
		if (val > 0) maxL = maxR = maxS = Segment(l, r, val);
		else {
			maxL = maxS = Segment(l, l, 0);
			maxR = Segment(r, r, 0);
		}
		if (val < 0) minL = minR = minS = Segment(l, r, val);
		else {
			minL = minS = Segment(l, l, 0);
			minR = Segment(r, r, 0);
		}
	}
	Tree(int l_, int r_) : l(l_), r(r_)
	{
		lc = l+1 < r ? new Tree(l, (l+r) >> 1) : NULL;
		rc = l+1 < r ? new Tree((l+r) >> 1, r) : NULL;
		chg = 0;
		if (l+1 < r) fresh();
		else setNode(a[l]);
	}
	void fresh()
	{
		maxS = max(max(lc->maxS, rc->maxS), lc->maxR+rc->maxL);
		maxL = max(lc->maxL, lc->sum+rc->maxL);
		maxR = max(rc->maxR, lc->maxR+rc->sum);
		minS = min(min(lc->minS, rc->minS), lc->minR+rc->minL);
		minL = min(lc->minL, lc->sum+rc->minL);
		minR = min(rc->minR, lc->minR+rc->sum);
		sum = lc->sum+rc->sum;
	}
	void modify()
	{
		chg ^= 1;
		swap(minL, maxL);
		swap(minR, maxR);
		swap(minS, maxS);
		maxL.sum = -maxL.sum;
		maxR.sum = -maxR.sum;
		maxS.sum = -maxS.sum;
		minL.sum = -minL.sum;
		minR.sum = -minR.sum;
		minS.sum = -minS.sum;
		sum.sum = -sum.sum;
	}
	void down()
	{
		chg = 0;
		lc->modify();
		rc->modify();
	}
	void change(int x, int y)
	{
		if (l+1 == r) setNode(y);
		else {
			if (chg) down();
			x < (l+r) >> 1 ? lc->change(x, y) : rc->change(x, y);
			fresh();
		}
	}
	void query(int ll, int rr)
	{
		if (ll <= l && rr >= r) {
			cntS = max(max(cntS, maxS), cntR+maxL);
			cntR = max(maxR, cntR+sum);
		}
		else {
			if (chg) down();
			if (ll < (l+r) >> 1) lc->query(ll, rr);
			if (rr > (l+r) >> 1) rc->query(ll, rr);
			fresh();
		}
	}
	void negative(int ll, int rr)
	{
		if (ll <= l && rr >= r) modify();
		else {
			if (chg) down();
			if (ll < (l+r) >> 1) lc->negative(ll, rr);
			if (rr > (l+r) >> 1) rc->negative(ll, rr);
			fresh();
		}
	}
} *root;
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n, m;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", a+i);
	root = new Tree(0, n);
	scanf("%d", &m);
	for (int i = 0; i < m; i++) {
		int opt;
		scanf("%d", &opt);
		if (opt == 0) {
			int pos, val;
			scanf("%d%d", &pos, &val); pos--;
			root->change(pos, val);
		}
		else {
			int l, r, k, res = 0;
			scanf("%d%d%d", &l, &r, &k); l--;
			vector<PII> b;
			for (int i = 0; i < k; i++) {
				cntS = cntR = Segment(l, l, 0);
				root->query(l, r);
				res += cntS.sum;
				if (cntS.l < cntS.r) {
					root->negative(cntS.l, cntS.r);
					b.pb(mp(cntS.l, cntS.r));
				}
				else break;
			}
			for (int i = 0; i < b.size(); i++)
				root->negative(b[i].first, b[i].second);
			printf("%d\n", res);
		}
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <bitset>
#include <cmath>
#include <ctime>
#include <cassert>
using namespace std;

#define pb push_back
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (n); i++)
#define foreach(e, x) for (__typeof(x.begin()) e = x.begin(); e != x.end(); e++)
#define FAST_IO std::ios::sync_with_stdio(false)
typedef long long LL;
typedef pair<int, int> PII;
int rd() { return RAND_MAX == 32767 ? ((rand() << 15) ^ rand()) : rand(); }

const int maxn = 100010;
const int inf = 1000000000;

int a[maxn], opt[21][2][2], w[21][2][2];

inline void modify(int &x, int y)
{
	if (y > x) x = y;
}
inline void fresh(int f[21][2][2], int x[21][2][2], int y[21][2][2])
{
	for (int i = 0; i <= 20; i++)
		for (int j = 0; j < 2; j++)
			for (int k = 0; k < 2; k++) {
				f[i][j][k] = -inf;
				for (int l = 0; l <= i; l++) {
					modify(f[i][j][k], x[l][j][0]+y[i-l][0][k]);
					modify(f[i][j][k], x[l][j][0]+y[i-l][1][k]);
					modify(f[i][j][k], x[l][j][1]+y[i-l][0][k]);
					modify(f[i][j][k], x[l][j][1]+y[i-l][1][k]);
				}
				for (int l = 1; l <= i; l++)
					modify(f[i][j][k], x[l][j][1]+y[i+1-l][1][k]);
			}
	for (int i = 1; i <= 20; i++)
		for (int j = 1; j >= 0; j--)
			for (int k = 1; k >= 0; k--)
				modify(f[i][j][k], f[i-1][j][k]);
}
struct Tree
{
	int l, r;
	int f[21][2][2];
	Tree *lc, *rc;

	Tree(int l_, int r_) : l(l_), r(r_)
	{
		lc = l+1 < r ? new Tree(l, (l+r) >> 1) : NULL;
		rc = l+1 < r ? new Tree((l+r) >> 1, r) : NULL;
		if (l+1 == r)
			fresh_node(a[l]);
		else
			fresh(f, lc->f, rc->f);
	}
	void fresh_node(int x)
	{
		for (int i = 1; i <= 20; i++) {
			f[i][0][0] = 0;
			f[i][0][1] = f[i][1][0] = -inf;
			f[i][1][1] = x;
		}
		f[0][0][0] = 0;
		f[0][0][1] = f[0][1][0] = f[0][1][1] = -inf;
	}
	void change(int pos, int val)
	{
		if (l+1 == r)
			fresh_node(val);
		else {
			pos < (l+r) >> 1 ? lc->change(pos, val) : rc->change(pos, val);
			fresh(f, lc->f, rc->f);
		}
	}
	void query(int ll, int rr)
	{
		if (ll <= l && rr >= r) {
			if (opt[0][0][0] == -1)
				memcpy(opt, f, sizeof(f));
			else {
				fresh(w, opt, f);
				memcpy(opt, w, sizeof(w));
			}
		}
		else {
			if (ll < (l+r) >> 1) lc->query(ll, rr);
			if (rr > (l+r) >> 1) rc->query(ll, rr);
		}
	}
} *root;
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n, m;
	cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i];
	root = new Tree(0, n);
	cin >> m;
	for (int i = 0; i < m; i++) {
		int ret;
		cin >> ret;
		if (ret == 0) {
			int pos, val;
			cin >> pos >> val; pos--;
			root->change(pos, val);
		}
		else {
			int l, r, k;
			cin >> l >> r >> k; l--;
			opt[0][0][0] = -1;
			root->query(l, r);
			cout << max(max(max(opt[k][0][0], opt[k][0][1]), opt[k][1][0]), opt[k][1][1]) << endl;
		}
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <bitset>
#include <cmath>
#include <ctime>
#include <cassert>
using namespace std;

#define pb push_back
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (n); i++)
#define foreach(e, x) for (__typeof(x.begin()) e = x.begin(); e != x.end(); e++)
#define FAST_IO std::ios::sync_with_stdio(false)
typedef long long LL;
typedef pair<int, int> PII;
int rd() { return RAND_MAX == 32767 ? ((rand() << 15) ^ rand()) : rand(); }

const int maxn = 100010;

int a[maxn];

struct Segment
{
	int l, r, sum;

	Segment() {}
	Segment(int l_, int r_, int sum_) : l(l_), r(r_), sum(sum_) {}
	Segment operator + (const Segment &o) const
	{
		Segment res;
		res.sum = sum+o.sum;
		res.l = l;
		res.r = o.r;
		return res;
	}
	bool operator < (const Segment &o) const
	{
		return sum < o.sum;
	}
} cntR, cntS;
struct Tree
{
	int l, r, chg;
	Segment sum, maxL, maxR, maxS, minL, minR, minS;
	Tree *lc, *rc;

	void setNode(int val)
	{
		sum = Segment(l, r, val);
		if (val > 0) maxL = maxR = maxS = Segment(l, r, val);
		else {
			maxL = maxS = Segment(l, l, 0);
			maxR = Segment(r, r, 0);
		}
		if (val < 0) minL = minR = minS = Segment(l, r, val);
		else {
			minL = minS = Segment(l, l, 0);
			minR = Segment(r, r, 0);
		}
	}
	Tree(int l_, int r_) : l(l_), r(r_)
	{
		lc = l+1 < r ? new Tree(l, (l+r) >> 1) : NULL;
		rc = l+1 < r ? new Tree((l+r) >> 1, r) : NULL;
		chg = 0;
		if (l+1 < r) fresh();
		else setNode(a[l]);
	}
	void fresh()
	{
		maxS = max(max(lc->maxS, rc->maxS), lc->maxR+rc->maxL);
		maxL = max(lc->maxL, lc->sum+rc->maxL);
		maxR = max(rc->maxR, rc->sum+lc->maxR);
		minS = min(min(lc->minS, rc->minS), lc->minR+rc->minL);
		minL = min(lc->minL, lc->sum+rc->minL);
		minR = min(rc->minR, rc->sum+lc->minR);
		sum = lc->sum+rc->sum;
	}
	void modify()
	{
		chg ^= 1;
		swap(minL, maxL);
		swap(minR, maxR);
		swap(minS, maxS);
		maxL.sum = -maxL.sum;
		maxR.sum = -maxR.sum;
		maxS.sum = -maxS.sum;
		minL.sum = -minL.sum;
		minR.sum = -minR.sum;
		minS.sum = -minS.sum;
		sum.sum = -sum.sum;
	}
	void down()
	{
		chg = 0;
		lc->modify();
		rc->modify();
	}
	void change(int x, int y)
	{
		if (l+1 == r) setNode(y);
		else {
			if (chg) down();
			x < (l+r) >> 1 ? lc->change(x, y) : rc->change(x, y);
			fresh();
		}
	}
	void query(int ll, int rr)
	{
		if (ll <= l && rr >= r) {
			cntS = max(max(cntS, maxS), cntR+maxL);
			cntR = max(maxR, cntR+sum);
		}
		else {
			if (chg) down();
			if (ll < (l+r) >> 1) lc->query(ll, rr);
			if (rr > (l+r) >> 1) rc->query(ll, rr);
			fresh();
		}
	}
	void negative(int ll, int rr)
	{
		if (ll <= l && rr >= r) modify();
		else {
			if (chg) down();
			if (ll < (l+r) >> 1) lc->negative(ll, rr);
			if (rr > (l+r) >> 1) rc->negative(ll, rr);
			fresh();
		}
	}
} *root;
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n, m;
	cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i];
	root = new Tree(0, n);
	cin >> m;
	for (int i = 0; i < m; i++) {
		int opt;
		cin >> opt;
		if (opt == 0) {
			int pos, val;
			cin >> pos >> val; pos--;
			root->change(pos, val);
		}
		else {
			int l, r, k, res = 0;
			cin >> l >> r >> k; l--;
			vector<PII> b;
			for (int i = 0; i < k; i++) {
				cntS = cntR = Segment(l, l, 0);
				root->query(l, r);
				res += cntS.sum;
				if (cntS.l < cntS.r) {
					root->negative(cntS.l, cntS.r);
					b.pb(mp(cntS.l, cntS.r));
				}
				else break;
			}
			for (int i = 0; i < b.size(); i++)
				root->negative(b[i].first, b[i].second);
			cout << res << endl;
		}
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int maxn = 100010;
const int inf = 1000000000;

int n, m, rt;
int a[maxn], b[maxn], p[maxn], add[maxn], chg[maxn], rev[maxn], key[maxn], ch[maxn][2];

struct Segment
{
	int l, r, val;
	Segment() {}
	Segment(int l_, int r_, int val_) : l(l_), r(r_), val(val_) {}
	Segment operator + (const Segment &o) const
	{
		if (l == -7 && o.l == -7)
			return Segment(-7, -7, 0);
		else if (l == -7)
			return o;
		else if (o.l == -7)
			return *this;
		else
			return Segment(l, o.r, val+o.val);
	}
	bool operator < (const Segment &o) const
	{
		return val < o.val;
	}
	void operator += (int x)
	{
		l += x;
		r += x;
	}
	void swap()
	{
		l ^= r; r ^= l; l ^= r;
	}
} c[30], sum[maxn], maxL[maxn], maxR[maxn], maxS[maxn], minL[maxn], minR[maxn], minS[maxn];
inline void nag(int &x)
{
	x = -x;
}
void setNode(int t, int val)
{
	key[t] = val;
	sum[t] = Segment(t-1, t, val);
	if (val > 0) maxL[t] = maxR[t] = maxS[t] = Segment(t-1, t, val);
	else {
		maxL[t] = maxS[t] = Segment(t-1, t-1, 0);
		maxR[t] = Segment(t, t, 0);
	}
	if (val < 0) minL[t] = minR[t] = minS[t] = Segment(t-1, t, val);
	else {
		minL[t] = minS[t] = Segment(t-1, t-1, 0);
		minR[t] = Segment(t, t, 0);
	}
}
void freshNode(int t)
{
	int lc = ch[t][0], rc = ch[t][1];
	Segment cnt(t-1, t, key[t]);
	maxS[t] = max(max(maxS[lc], maxS[rc]), maxR[lc]+cnt+maxL[rc]);
	maxL[t] = max(maxL[lc], sum[lc]+cnt+maxL[rc]);
	maxR[t] = max(maxR[rc], maxR[lc]+cnt+sum[rc]);
	minS[t] = min(min(minS[lc], minS[rc]), minR[lc]+cnt+minL[rc]);
	minL[t] = min(minL[lc], sum[lc]+cnt+minL[rc]);
	minR[t] = min(minR[rc], minR[lc]+cnt+sum[rc]);
	sum[t] = sum[lc]+cnt+sum[rc];
}
void change(int t)
{
	chg[t] ^= 1;
	swap(minL[t], maxL[t]);
	swap(minR[t], maxR[t]);
	swap(minS[t], maxS[t]);
	nag(maxL[t].val); nag(maxR[t].val); nag(maxS[t].val);
	nag(minL[t].val); nag(minR[t].val); nag(minS[t].val);
	nag(sum[t].val);
}
void overturn(int t, int add_, int rev_)
{
	if (rev_) {
		maxS[t].swap(); maxL[t].swap(); maxR[t].swap();
		minS[t].swap(); minL[t].swap(); minR[t].swap();
		sum[t].swap();
		swap(maxL[t], maxR[t]);
		swap(minL[t], minR[t]);
	}
	if (add_) {
		maxS[t] += add_; maxL[t] += add_; maxR[t] += add_;
		minS[t] += add_; minL[t] += add_; minR[t] += add_;
		sum[t] += add_;
	}
	add[t] = rev_ ? add_-add[t] : add_+add[t];
	rev[t] ^= rev_;
	if (rev_) swap(ch[t][0], ch[t][1]);
}
void downNode(int t)
{
	if (chg[t]) {
		chg[t] = 0;
		if (ch[t][0]) change(ch[t][0]);
		if (ch[t][1]) change(ch[t][1]);
	}
	if (add[t] || rev[t]) {
		if (ch[t][0]) overturn(ch[t][0], add[t], rev[t]);
		if (ch[t][1]) overturn(ch[t][1], add[t], rev[t]);
		add[t] = rev[t] = 0;
	}
}
int make_tree(int l, int r)
{
	int t = ((l+r) >> 1)+2;
	add[t] = chg[t] = rev[t] = 0;
	if (l+1 == r)
		setNode(t, a[l]);
	else {
		int m = (l+r) >> 1;
		ch[t][0] = l < m ? make_tree(l, m) : 0;
		ch[t][1] = m+1 < r ? make_tree(m+1, r) : 0;
		if (ch[t][0]) p[ch[t][0]] = t;
		if (ch[t][1]) p[ch[t][1]] = t;
		key[t] = a[m];
		freshNode(t);
	}
	return t;
}
void rotate(int t, int x)
{
	int k = ch[t][x];
	ch[t][x] = ch[k][1-x];
	ch[k][1-x] = t;
	if (p[t]) ch[p[t]][t == ch[p[t]][1]] = k;
	p[k] = p[t];
	p[t] = k;
	if (ch[t][x]) p[ch[t][x]] = t;
	maxL[k] = maxL[t]; maxR[k] = maxR[t]; maxS[k] = maxS[t];
	minL[k] = minL[t]; minR[k] = minR[t]; minS[k] = minS[t];
	sum[k] = sum[t];
	freshNode(t);
}
void splay(int t, int x)
{
	if (x == rt) rt = t;
	int m = 0;
	for (int k = t; k; k = p[k]) b[m++] = k;
	for (int i = m-1; i >= 0; i--) downNode(b[i]);
	while (t != x) {
		if (p[t] == x) {
			rotate(x, t == ch[x][1]);
			return;
		}
		int k = p[t], flag = p[p[t]] == x;
		if (t == ch[p[t]][1] ^ k == ch[p[k]][1]) {
			rotate(p[t], t == ch[p[t]][1]);
			rotate(p[t], t == ch[p[t]][1]);
		}
		else {
			rotate(p[k], k == ch[p[k]][1]);
			rotate(p[t], t == ch[p[t]][1]);
		}
		if (flag) return;
	}
}
void nagetive(int l, int r)
{
	splay(l, rt);
	splay(r+1, ch[rt][1]);
	change(ch[ch[rt][1]][0]);
}
void initialize()
{
	sum[0] = Segment(-7, -7, 0);
	maxS[0] = Segment(-7, -7, -inf);
	minS[0] = Segment(-7, -7, +inf);
	maxL[0] = maxR[0] = minL[0] = minR[0] = Segment(-7, -7, 0);
	p[0] = ch[0][0] = ch[0][1] = 0;
	int t = make_tree(0, n);
	ch[1][1] = n+2; p[n+2] = 1;
	key[1] = key[n+2] = p[1] = ch[1][0] = ch[n+2][1] = 0;
	add[1] = chg[1] = rev[1] = add[n+2] = chg[n+2] = rev[n+2] = 0;
	ch[n+2][0] = t; p[t] = n+2;
	freshNode(n+2);
	freshNode(1);
	rt = 1;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	// 1 pos val  change the value
	// 2 l r      reverse the interval
	// 3 l r k    query
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", a+i);
	initialize();
	for (scanf("%d", &m); m--; ) {
		int opt, pos, l, r, k, val;
		scanf("%d", &opt);
		if (opt == 0) {
			scanf("%d%d", &pos, &val);
			splay(pos+1, rt);
			key[pos+1] = val;
			freshNode(pos+1);
		}
		else if (opt == 2) {
			scanf("%d%d", &l, &r);
			splay(l, rt);
			splay(r+2, ch[rt][1]);
			overturn(ch[ch[rt][1]][0], l+r-1, 1);
			freshNode(ch[rt][1]);
			freshNode(rt);
		}
		else {
			scanf("%d%d%d", &l, &r, &k);
			int tot = 0, res = 0;
			for (int i = 0; i < k; i++) {
				splay(l, rt);
				splay(r+2, ch[rt][1]);
				Segment cnt = maxS[ch[ch[rt][1]][0]];
				if (cnt.l < cnt.r) {
					res += cnt.val;
					c[tot++] = cnt;
					nagetive(cnt.l, cnt.r);
				}
				else break;
			}
			printf("%d\n", res);
			for (int i = 0; i < tot; i++)
				nagetive(c[i].l, c[i].r);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn=100005,INF=0x7FFFFFFF;
struct data
{
	int Sum,Max,L,R,Lmax,Lto,Rmax,Rto;
	data() {}
	data(int A,int B,int C,int D,int E,int F,int G,int H):Sum(A),Max(B),L(C),R(D),Lmax(E),Lto(F),Rmax(G),Rto(H) {}
};
struct node
{
	int Sum[2],Max[2],L[2],R[2],Lmax[2],Lto[2],Rmax[2],Rto[2];
	bool flip;
} tree[maxn<<2];
int n,p,q,val[maxn],reL[maxn],reR[maxn];
void up(int root,int Lson,int Rson)
{
	for (int i=0;i<2;i++)
	{
		tree[root].Sum[i]=tree[Lson].Sum[i]+tree[Rson].Sum[i];
		tree[root].Max[i]=tree[Lson].Rmax[i]+tree[Rson].Lmax[i];
		tree[root].L[i]=tree[Lson].Rto[i];
		tree[root].R[i]=tree[Rson].Lto[i];
		if (tree[Lson].Max[i]>tree[root].Max[i])
		{
			tree[root].Max[i]=tree[Lson].Max[i];
			tree[root].L[i]=tree[Lson].L[i];
			tree[root].R[i]=tree[Lson].R[i];
		}
		if (tree[Rson].Max[i]>tree[root].Max[i])
		{
			tree[root].Max[i]=tree[Rson].Max[i];
			tree[root].L[i]=tree[Rson].L[i];
			tree[root].R[i]=tree[Rson].R[i];
		}
		tree[root].Lmax[i]=tree[Lson].Sum[i]+tree[Rson].Lmax[i];
		tree[root].Lto[i]=tree[Rson].Lto[i];
		if (tree[Lson].Lmax[i]>tree[root].Lmax[i])
		{
			tree[root].Lmax[i]=tree[Lson].Lmax[i];
			tree[root].Lto[i]=tree[Lson].Lto[i];
		}
		tree[root].Rmax[i]=tree[Rson].Sum[i]+tree[Lson].Rmax[i];
		tree[root].Rto[i]=tree[Lson].Rto[i];
		if (tree[Rson].Rmax[i]>tree[root].Rmax[i])
		{
			tree[root].Rmax[i]=tree[Rson].Rmax[i];
			tree[root].Rto[i]=tree[Rson].Rto[i];
		}
	}
}
void build(int root,int L,int R)
{
	if (L==R)
	{
		tree[root].Sum[0]=tree[root].Max[0]=tree[root].Lmax[0]=tree[root].Rmax[0]=val[L];
		tree[root].Sum[1]=tree[root].Max[1]=tree[root].Lmax[1]=tree[root].Rmax[1]=-val[L];
		tree[root].L[0]=tree[root].R[0]=tree[root].Lto[0]=tree[root].Rto[0]=L;
		tree[root].L[1]=tree[root].R[1]=tree[root].Lto[1]=tree[root].Rto[1]=L;
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	build(Lson,L,mid);
	build(Rson,mid+1,R);
	up(root,Lson,Rson);
}
void change(int root)
{
	swap(tree[root].Sum[0],tree[root].Sum[1]);
	swap(tree[root].Max[0],tree[root].Max[1]);
	swap(tree[root].L[0],tree[root].L[1]);
	swap(tree[root].R[0],tree[root].R[1]);
	swap(tree[root].Lmax[0],tree[root].Lmax[1]);
	swap(tree[root].Lto[0],tree[root].Lto[1]);
	swap(tree[root].Rmax[0],tree[root].Rmax[1]);
	swap(tree[root].Rto[0],tree[root].Rto[1]);
}
void down(int root,int Lson,int Rson)
{
	if (!tree[root].flip) return;
	change(Lson);
	change(Rson);
	tree[Lson].flip^=1;
	tree[Rson].flip^=1;
	tree[root].flip=0;
}
void update(int root,int L,int R,int x,int val)
{
	if (L==R)
	{
		tree[root].Sum[0]=tree[root].Max[0]=tree[root].Lmax[0]=tree[root].Rmax[0]=val;
		tree[root].Sum[1]=tree[root].Max[1]=tree[root].Lmax[1]=tree[root].Rmax[1]=-val;
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	if (x<=mid) update(Lson,L,mid,x,val); else update(Rson,mid+1,R,x,val);
	up(root,Lson,Rson);
}
data ask(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return data(0,0,0,0,0,0,0,0);
	if (x<=L && R<=y)
	{
		node T=tree[root];
		return data(T.Sum[0],T.Max[0],T.L[0],T.R[0],T.Lmax[0],T.Lto[0],T.Rmax[0],T.Rto[0]);
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	data Lres=ask(Lson,L,mid,x,y),Rres=ask(Rson,mid+1,R,x,y);
	if (!Lres.L) return Rres;
	if (!Rres.R) return Lres;
	data res=data(Lres.Sum+Rres.Sum,Lres.Rmax+Rres.Lmax,Lres.Rto,Rres.Lto,Lres.Sum+Rres.Lmax,Rres.Lto,Rres.Sum+Lres.Rmax,Lres.Rto);
	if (Lres.Max>res.Max)
	{
		res.Max=Lres.Max;
		res.L=Lres.L;
		res.R=Lres.R;
	}
	if (Rres.Max>res.Max)
	{
		res.Max=Rres.Max;
		res.L=Rres.L;
		res.R=Rres.R;
	}
	if (Lres.Lmax>res.Lmax)
	{
		res.Lmax=Lres.Lmax;
		res.Lto=Lres.Lto;
	}
	if (Rres.Rmax>res.Rmax)
	{
		res.Rmax=Rres.Rmax;
		res.Rto=Rres.Rto;
	}
	return res;
}
void flip(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return;
	if (x<=L && R<=y)
	{
		change(root);
		tree[root].flip^=1;
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	flip(Lson,L,mid,x,y);
	flip(Rson,mid+1,R,x,y);
	up(root,Lson,Rson);
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&val[i]);
	build(1,1,n);
	scanf("%d",&q);
	while (q--)
	{
		int ord,x,y;
		scanf("%d%d%d",&ord,&x,&y);
		if (!ord) update(1,1,n,x,y); else
		{
			int z,ans=0;
			scanf("%d",&z);
			while (z--)
			{
				data res=ask(1,1,n,x,y);
				if (res.Max<=0) break;
				ans+=res.Max;
				flip(1,1,n,res.L,res.R);
				p++;
				reL[p]=res.L;
				reR[p]=res.R;
			}
			printf("%d\n",ans);
			while (p)
			{
				flip(1,1,n,reL[p],reR[p]);
				p--;
			}
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn=100005,INF=0x7FFFFFFF;
struct data
{
	int Sum,Max,L,R,Lmax,Lto,Rmax,Rto;
	data() {}
	data(int A,int B,int C,int D,int E,int F,int G,int H):Sum(A),Max(B),L(C),R(D),Lmax(E),Lto(F),Rmax(G),Rto(H) {}
};
struct node
{
	int Sum[2],Max[2],L[2],R[2],Lmax[2],Lto[2],Rmax[2],Rto[2];
	bool flip,reset;
} tree[maxn<<2],clo[maxn<<2];
int n,q,val[maxn];
void up(int root,int Lson,int Rson)
{
	for (int i=0;i<2;i++)
	{
		tree[root].Sum[i]=tree[Lson].Sum[i]+tree[Rson].Sum[i];
		tree[root].Max[i]=tree[Lson].Rmax[i]+tree[Rson].Lmax[i];
		tree[root].L[i]=tree[Lson].Rto[i];
		tree[root].R[i]=tree[Rson].Lto[i];
		if (tree[Lson].Max[i]>tree[root].Max[i])
		{
			tree[root].Max[i]=tree[Lson].Max[i];
			tree[root].L[i]=tree[Lson].L[i];
			tree[root].R[i]=tree[Lson].R[i];
		}
		if (tree[Rson].Max[i]>tree[root].Max[i])
		{
			tree[root].Max[i]=tree[Rson].Max[i];
			tree[root].L[i]=tree[Rson].L[i];
			tree[root].R[i]=tree[Rson].R[i];
		}
		tree[root].Lmax[i]=tree[Lson].Sum[i]+tree[Rson].Lmax[i];
		tree[root].Lto[i]=tree[Rson].Lto[i];
		if (tree[Lson].Lmax[i]>tree[root].Lmax[i])
		{
			tree[root].Lmax[i]=tree[Lson].Lmax[i];
			tree[root].Lto[i]=tree[Lson].Lto[i];
		}
		tree[root].Rmax[i]=tree[Rson].Sum[i]+tree[Lson].Rmax[i];
		tree[root].Rto[i]=tree[Lson].Rto[i];
		if (tree[Rson].Rmax[i]>tree[root].Rmax[i])
		{
			tree[root].Rmax[i]=tree[Rson].Rmax[i];
			tree[root].Rto[i]=tree[Rson].Rto[i];
		}
	}
}
void build(int root,int L,int R)
{
	if (L==R)
	{
		tree[root].Sum[0]=tree[root].Max[0]=tree[root].Lmax[0]=tree[root].Rmax[0]=val[L];
		tree[root].Sum[1]=tree[root].Max[1]=tree[root].Lmax[1]=tree[root].Rmax[1]=-val[L];
		tree[root].L[0]=tree[root].R[0]=tree[root].Lto[0]=tree[root].Rto[0]=L;
		tree[root].L[1]=tree[root].R[1]=tree[root].Lto[1]=tree[root].Rto[1]=L;
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	build(Lson,L,mid);
	build(Rson,mid+1,R);
	up(root,Lson,Rson);
}
void change(int root)
{
	swap(tree[root].Sum[0],tree[root].Sum[1]);
	swap(tree[root].Max[0],tree[root].Max[1]);
	swap(tree[root].L[0],tree[root].L[1]);
	swap(tree[root].R[0],tree[root].R[1]);
	swap(tree[root].Lmax[0],tree[root].Lmax[1]);
	swap(tree[root].Lto[0],tree[root].Lto[1]);
	swap(tree[root].Rmax[0],tree[root].Rmax[1]);
	swap(tree[root].Rto[0],tree[root].Rto[1]);
}
void down(int root,int Lson,int Rson)
{
	if (tree[root].reset)
	{
		tree[Lson]=clo[Lson];
		tree[Rson]=clo[Rson];
		tree[Lson].reset=1;
		tree[Rson].reset=1;
		tree[root].reset=0;
		tree[root].flip=0;
	} else
	if (tree[root].flip)
	{
		change(Lson);
		change(Rson);
		tree[Lson].flip^=1;
		tree[Rson].flip^=1;
		tree[root].flip=0;
	}
}
void update(int root,int L,int R,int x,int val)
{
	if (L==R)
	{
		tree[root].Sum[0]=tree[root].Max[0]=tree[root].Lmax[0]=tree[root].Rmax[0]=val;
		tree[root].Sum[1]=tree[root].Max[1]=tree[root].Lmax[1]=tree[root].Rmax[1]=-val;
		clo[root]=tree[root];
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	if (x<=mid) update(Lson,L,mid,x,val); else update(Rson,mid+1,R,x,val);
	up(root,Lson,Rson);
	clo[root]=tree[root];
}
data ask(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return data(0,0,0,0,0,0,0,0);
	if (x<=L && R<=y)
	{
		node T=tree[root];
		return data(T.Sum[0],T.Max[0],T.L[0],T.R[0],T.Lmax[0],T.Lto[0],T.Rmax[0],T.Rto[0]);
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	data Lres=ask(Lson,L,mid,x,y),Rres=ask(Rson,mid+1,R,x,y);
	if (!Lres.L) return Rres;
	if (!Rres.R) return Lres;
	data res=data(Lres.Sum+Rres.Sum,Lres.Rmax+Rres.Lmax,Lres.Rto,Rres.Lto,Lres.Sum+Rres.Lmax,Rres.Lto,Rres.Sum+Lres.Rto,Lres.Rto);
	if (Lres.Max>res.Max)
	{
		res.Max=Lres.Max;
		res.L=Lres.L;
		res.R=Lres.R;
	}
	if (Rres.Max>res.Max)
	{
		res.Max=Rres.Max;
		res.L=Rres.L;
		res.R=Rres.R;
	}
	if (Lres.Lmax>res.Lmax)
	{
		res.Lmax=Lres.Lmax;
		res.Lto=Lres.Lto;
	}
	if (Rres.Rmax>res.Rmax)
	{
		res.Rmax=Rres.Rmax;
		res.Rto=Rres.Rto;
	}
	return res;
}
void flip(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return;
	if (x<=L && R<=y)
	{
		change(root);
		tree[root].flip^=1;
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	flip(Lson,L,mid,x,y);
	flip(Rson,mid+1,R,x,y);
	up(root,Lson,Rson);
}
void reset(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return;
	if (x<=L && R<=y)
	{
		tree[root]=clo[root];
		tree[root].reset=1;
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	reset(Lson,L,mid,x,y);
	reset(Rson,mid+1,R,x,y);
	up(root,Lson,Rson);
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&val[i]);
	build(1,1,n);
	memcpy(clo,tree,sizeof(tree));
	scanf("%d",&q);
	while (q--)
	{
		int ord,x,y;
		scanf("%d%d%d",&ord,&x,&y);
		if (!ord) update(1,1,n,x,y); else
		{
			int z,ans=0;
			scanf("%d",&z);
			for (int i=1;i<=z;i++)
			{
				data res=ask(1,1,n,x,y);
				if (res.Max<=0) break;
				ans+=res.Max;
				flip(1,1,n,res.L,res.R);
			}
			printf("%d\n",ans);
			reset(1,1,n,x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn=100005,INF=0x7FFFFFFF;
struct data
{
	int Sum,Max,L,R,Lmax,Lto,Rmax,Rto;
	data() {}
	data(int A,int B,int C,int D,int E,int F,int G,int H):Sum(A),Max(B),L(C),R(D),Lmax(E),Lto(F),Rmax(G),Rto(H) {}
};
struct node
{
	int Sum[2],Max[2],L[2],R[2],Lmax[2],Lto[2],Rmax[2],Rto[2];
	bool flip;
} tree[maxn<<2],clo[maxn<<2];
int n,p,q,val[maxn],reL[maxn],reR[maxn];
void up(int root,int Lson,int Rson)
{
	for (int i=0;i<2;i++)
	{
		tree[root].Sum[i]=tree[Lson].Sum[i]+tree[Rson].Sum[i];
		tree[root].Max[i]=tree[Lson].Rmax[i]+tree[Rson].Lmax[i];
		tree[root].L[i]=tree[Lson].Rto[i];
		tree[root].R[i]=tree[Rson].Lto[i];
		if (tree[Lson].Max[i]>tree[root].Max[i])
		{
			tree[root].Max[i]=tree[Lson].Max[i];
			tree[root].L[i]=tree[Lson].L[i];
			tree[root].R[i]=tree[Lson].R[i];
		}
		if (tree[Rson].Max[i]>tree[root].Max[i])
		{
			tree[root].Max[i]=tree[Rson].Max[i];
			tree[root].L[i]=tree[Rson].L[i];
			tree[root].R[i]=tree[Rson].R[i];
		}
		tree[root].Lmax[i]=tree[Lson].Sum[i]+tree[Rson].Lmax[i];
		tree[root].Lto[i]=tree[Rson].Lto[i];
		if (tree[Lson].Lmax[i]>tree[root].Lmax[i])
		{
			tree[root].Lmax[i]=tree[Lson].Lmax[i];
			tree[root].Lto[i]=tree[Lson].Lto[i];
		}
		tree[root].Rmax[i]=tree[Rson].Sum[i]+tree[Lson].Rmax[i];
		tree[root].Rto[i]=tree[Lson].Rto[i];
		if (tree[Rson].Rmax[i]>tree[root].Rmax[i])
		{
			tree[root].Rmax[i]=tree[Rson].Rmax[i];
			tree[root].Rto[i]=tree[Rson].Rto[i];
		}
	}
}
void build(int root,int L,int R)
{
	if (L==R)
	{
		tree[root].Sum[0]=tree[root].Max[0]=tree[root].Lmax[0]=tree[root].Rmax[0]=val[L];
		tree[root].Sum[1]=tree[root].Max[1]=tree[root].Lmax[1]=tree[root].Rmax[1]=-val[L];
		tree[root].L[0]=tree[root].R[0]=tree[root].Lto[0]=tree[root].Rto[0]=L;
		tree[root].L[1]=tree[root].R[1]=tree[root].Lto[1]=tree[root].Rto[1]=L;
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	build(Lson,L,mid);
	build(Rson,mid+1,R);
	up(root,Lson,Rson);
}
void change(int root)
{
	swap(tree[root].Sum[0],tree[root].Sum[1]);
	swap(tree[root].Max[0],tree[root].Max[1]);
	swap(tree[root].L[0],tree[root].L[1]);
	swap(tree[root].R[0],tree[root].R[1]);
	swap(tree[root].Lmax[0],tree[root].Lmax[1]);
	swap(tree[root].Lto[0],tree[root].Lto[1]);
	swap(tree[root].Rmax[0],tree[root].Rmax[1]);
	swap(tree[root].Rto[0],tree[root].Rto[1]);
}
void down(int root,int Lson,int Rson)
{
	if (!tree[root].flip) return;
	change(Lson);
	change(Rson);
	tree[Lson].flip^=1;
	tree[Rson].flip^=1;
	tree[root].flip=0;
}
void update(int root,int L,int R,int x,int val)
{
	if (L==R)
	{
		tree[root].Sum[0]=tree[root].Max[0]=tree[root].Lmax[0]=tree[root].Rmax[0]=val;
		tree[root].Sum[1]=tree[root].Max[1]=tree[root].Lmax[1]=tree[root].Rmax[1]=-val;
		clo[root]=tree[root];
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	if (x<=mid) update(Lson,L,mid,x,val); else update(Rson,mid+1,R,x,val);
	up(root,Lson,Rson);
	clo[root]=tree[root];
}
data ask(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return data(0,0,0,0,0,0,0,0);
	if (x<=L && R<=y)
	{
		node T=tree[root];
		return data(T.Sum[0],T.Max[0],T.L[0],T.R[0],T.Lmax[0],T.Lto[0],T.Rmax[0],T.Rto[0]);
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	data Lres=ask(Lson,L,mid,x,y),Rres=ask(Rson,mid+1,R,x,y);
	if (!Lres.L) return Rres;
	if (!Rres.R) return Lres;
	data res=data(Lres.Sum+Rres.Sum,Lres.Rmax+Rres.Lmax,Lres.Rto,Rres.Lto,Lres.Sum+Rres.Lmax,Rres.Lto,Rres.Sum+Lres.Rto,Lres.Rto);
	if (Lres.Max>res.Max)
	{
		res.Max=Lres.Max;
		res.L=Lres.L;
		res.R=Lres.R;
	}
	if (Rres.Max>res.Max)
	{
		res.Max=Rres.Max;
		res.L=Rres.L;
		res.R=Rres.R;
	}
	if (Lres.Lmax>res.Lmax)
	{
		res.Lmax=Lres.Lmax;
		res.Lto=Lres.Lto;
	}
	if (Rres.Rmax>res.Rmax)
	{
		res.Rmax=Rres.Rmax;
		res.Rto=Rres.Rto;
	}
	return res;
}
void flip(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return;
	if (x<=L && R<=y)
	{
		change(root);
		tree[root].flip^=1;
		return;
	}
	int mid=L+R>>1,Lson=root<<1,Rson=Lson^1;
	down(root,Lson,Rson);
	flip(Lson,L,mid,x,y);
	flip(Rson,mid+1,R,x,y);
	up(root,Lson,Rson);
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&val[i]);
	build(1,1,n);
	memcpy(clo,tree,sizeof(tree));
	scanf("%d",&q);
	while (q--)
	{
		int ord,x,y;
		scanf("%d%d%d",&ord,&x,&y);
		if (!ord) update(1,1,n,x,y); else
		{
			int z,ans=0;
			scanf("%d",&z);
			while (z--)
			{
				data res=ask(1,1,n,x,y);
				if (res.Max<=0) break;
				ans+=res.Max;
				flip(1,1,n,res.L,res.R);
				p++;
				reL[p]=res.L;
				reR[p]=res.R;
			}
			printf("%d\n",ans);
			while (p)
			{
				flip(1,1,n,reL[p],reR[p]);
				p--;
			}
		}
	}
	return 0;
}


#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100005,maxm=25;
struct node
{
	int I,Sum[2],Max[2],L[2],R[2],Lmax[2],Lto[2],Rmax[2],Rto[2];
	bool boo;
} tree[maxn<<2];
struct data
{
	int Sum,Max,L,R,Lmax,Lto,Rmax,Rto;
	data() {}
	data(int A,int B,int C,int D,int E,int F,int G,int H):Sum(A),Max(B),L(C),R(D),Lmax(E),Lto(F),Rmax(G),Rto(H) {}
};
int G,n,q,p,ans,val[maxn],reL[maxm],reR[maxm];
void check1(int root,int i,int A,int B,int C)
{
	if (A<=tree[root].Max[i]) return;
	tree[root].Max[i]=A;
	tree[root].L[i]=B;
	tree[root].R[i]=C;
}
void check2(int root,int i,int A,int B)
{
	if (A<=tree[root].Lmax[i]) return;
	tree[root].Lmax[i]=A;
	tree[root].Lto[i]=B;
}
void check3(int root,int i,int A,int B)
{
	if (A<=tree[root].Rmax[i]) return;
	tree[root].Rmax[i]=A;
	tree[root].Rto[i]=B;
}
void build(int root,int L,int R)
{
	if (L==R)
	{
		tree[root].I=0;
		tree[root].boo=false;
		tree[root].Sum[0]=val[L];
		tree[root].Max[0]=val[L];
		tree[root].Lmax[0]=val[L];
		tree[root].Rmax[0]=val[L];
		tree[root].Sum[1]=-val[L];
		tree[root].Max[1]=-val[L];
		tree[root].Lmax[1]=-val[L];
		tree[root].Rmax[1]=-val[L];
		for (int i=0;i<=1;i++)
		{
			tree[root].L[i]=L;
			tree[root].R[i]=L;
			tree[root].Lto[i]=L;
			tree[root].Rto[i]=L;
		}
		return;
	}
	int mid=(L+R)>>1,Lson=root<<1,Rson=Lson+1;
	build(Lson,L,mid);
	build(Rson,mid+1,R);
	for (int i=0;i<=1;i++)
	{
		tree[root].Sum[i]=tree[Lson].Sum[i]+tree[Rson].Sum[i];
		tree[root].Max[i]=tree[Lson].Rmax[i]+tree[Rson].Lmax[i];
		tree[root].L[i]=tree[Lson].Rto[i];
		tree[root].R[i]=tree[Rson].Lto[i];
		check1(root,i,tree[Lson].Max[i],tree[Lson].L[i],tree[Lson].R[i]);
		check1(root,i,tree[Rson].Max[i],tree[Rson].L[i],tree[Rson].R[i]);
		tree[root].Lmax[i]=tree[Lson].Sum[i]+tree[Rson].Lmax[i];
		tree[root].Lto[i]=tree[Rson].Lto[i];
		check2(root,i,tree[Lson].Lmax[i],tree[Lson].Lto[i]);
		tree[root].Rmax[i]=tree[Rson].Sum[i]+tree[Lson].Rmax[i];
		tree[root].Rto[i]=tree[Lson].Rto[i];
		check3(root,i,tree[Rson].Rmax[i],tree[Rson].Rto[i]);
	}
}
void update(int root,int L,int R,int x,int val)
{
	if (L==R)
	{
		tree[root].I=0;
		tree[root].boo=false;
		tree[root].Sum[0]=val;
		tree[root].Max[0]=val;
		tree[root].Lmax[0]=val;
		tree[root].Rmax[0]=val;
		tree[root].Sum[1]=-val;
		tree[root].Max[1]=-val;
		tree[root].Lmax[1]=-val;
		tree[root].Rmax[1]=-val;
		for (int i=0;i<=1;i++)
		{
			tree[root].L[i]=L;
			tree[root].R[i]=L;
			tree[root].Lto[i]=L;
			tree[root].Rto[i]=L;
		}
		return;
	}
	int mid=(L+R)>>1,Lson=root<<1,Rson=Lson+1;
	if (x<=mid) update(Lson,L,mid,x,val);
	       else update(Rson,mid+1,R,x,val);
	for (int i=0;i<=1;i++)
	{
		tree[root].Sum[i]=tree[Lson].Sum[i]+tree[Rson].Sum[i];
		tree[root].Max[i]=tree[Lson].Rmax[i]+tree[Rson].Lmax[i];
		tree[root].L[i]=tree[Lson].Rto[i];
		tree[root].R[i]=tree[Rson].Lto[i];
		check1(root,i,tree[Lson].Max[i],tree[Lson].L[i],tree[Lson].R[i]);
		check1(root,i,tree[Rson].Max[i],tree[Rson].L[i],tree[Rson].R[i]);
		tree[root].Lmax[i]=tree[Lson].Sum[i]+tree[Rson].Lmax[i];
		tree[root].Lto[i]=tree[Rson].Lto[i];
		check2(root,i,tree[Lson].Lmax[i],tree[Lson].Lto[i]);
		tree[root].Rmax[i]=tree[Rson].Sum[i]+tree[Lson].Rmax[i];
		tree[root].Rto[i]=tree[Lson].Rto[i];
		check3(root,i,tree[Rson].Rmax[i],tree[Rson].Rto[i]);
	}
}
void down(int root,int Lson,int Rson)
{
	if (!tree[root].boo) return;
	tree[Lson].I^=1;
	tree[Lson].boo^=true;
	tree[Rson].I^=1;
	tree[Rson].boo^=true;
	tree[root].boo=false;
}
void flip(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return;
	if (x<=L && R<=y)
	{
		tree[root].I^=1;
		tree[root].boo^=true;
		return;
	}
	int mid=(L+R)>>1,Lson=root<<1,Rson=Lson+1;
	down(root,Lson,Rson);
	flip(Lson,L,mid,x,y);
	flip(Rson,mid+1,R,x,y);
	int i=tree[root].I,
	    i1=tree[Lson].I,
		i2=tree[Rson].I;
	for (int k=0;k<=1;k++)
	{
		tree[root].Sum[i]=tree[Lson].Sum[i1]+tree[Rson].Sum[i2];
		tree[root].Max[i]=tree[Lson].Rmax[i1]+tree[Rson].Lmax[i2];
		tree[root].L[i]=tree[Lson].Rto[i1];
		tree[root].R[i]=tree[Rson].Lto[i2];
		check1(root,i,tree[Lson].Max[i1],tree[Lson].L[i1],tree[Lson].R[i1]);
		check1(root,i,tree[Rson].Max[i2],tree[Rson].L[i2],tree[Rson].R[i2]);
		tree[root].Lmax[i]=tree[Lson].Sum[i1]+tree[Rson].Lmax[i2];
		tree[root].Lto[i]=tree[Rson].Lto[i2];
		check2(root,i,tree[Lson].Lmax[i1],tree[Lson].Lto[i1]);
		tree[root].Rmax[i]=tree[Rson].Sum[i2]+tree[Lson].Rmax[i1];
		tree[root].Rto[i]=tree[Lson].Rto[i1];
		check3(root,i,tree[Rson].Rmax[i2],tree[Rson].Rto[i2]);
		i^=1;
		i1^=1;
		i2^=1;
    }
}
data ask(int root,int L,int R,int x,int y)
{
	if (y<L || R<x) return data(0,0,0,0,0,0,0,0);
	if (x<=L && R<=y)
	{
		int i=tree[root].I;
		return data(tree[root].Sum[i],tree[root].Max[i],tree[root].L[i],tree[root].R[i],
		            tree[root].Lmax[i],tree[root].Lto[i],tree[root].Rmax[i],tree[root].Rto[i]);
	}
	int mid=(L+R)>>1,Lson=root<<1,Rson=Lson+1;
	down(root,Lson,Rson);
	data LL=ask(Lson,L,mid,x,y),RR=ask(Rson,mid+1,R,x,y),res;
	if (!LL.L) return RR;
	if (!RR.L) return LL;
	res.Sum=LL.Sum+RR.Sum;
	res.Max=LL.Rmax+RR.Lmax;
	res.L=LL.Rto;
	res.R=RR.Lto;
	if (LL.Max>res.Max) res.Max=LL.Max,res.L=LL.L,res.R=LL.R;
	if (RR.Max>res.Max) res.Max=RR.Max,res.L=RR.L,res.R=RR.R;
	res.Lmax=LL.Sum+RR.Lmax;
	res.Lto=RR.Lto;
	if (LL.Lmax>res.Lmax) res.Lmax=LL.Lmax,res.Lto=LL.Lto;
	res.Rmax=RR.Sum+LL.Rmax;
	res.Rto=LL.Rto;
	if (RR.Rmax>res.Rmax) res.Rmax=RR.Rmax,res.Rto=RR.Rto;
	return res;
}
int main()
{
		scanf("%d",&n);
		for (int i=1;i<=n;i++) scanf("%d",&val[i]);
		scanf("%d",&q);
		build(1,1,n);
		while (q--)
		{
			int ord,x,y,z;
			scanf("%d%d%d",&ord,&x,&y);
			if (!ord) update(1,1,n,x,y); else
			{
				p=0;
				ans=0;
				scanf("%d",&z);
				while (z--)
				{
					data res=ask(1,1,n,x,y);
					if (res.Max<=0) break;
					ans+=res.Max;
					p++;
					reL[p]=res.L;
					reR[p]=res.R;
					flip(1,1,n,reL[p],reR[p]);
				}
				for (int i=1;i<=p;i++) flip(1,1,n,reL[i],reR[i]);
				printf("%d\n",ans);
			}
		}
	return 0;
}


#include<bits/stdc++.h>
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Mem(a, b) memset((a), sizeof((a)), (b))
#define INF (0x7f7f7f7f)
#define N (2000005)
#define lson (u << 1)
#define rson (u << 1 | 1)
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
	int f = 0, ch = 0; x = 0;
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
	for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
	if(f) x = -x;
}
struct Point{
	int sl, pl, sr, pr, ans, al, ar, sum;
	inline Point() { sl = pl = sr = pr = ans = ar = sum = 0; }
};
int a[N], n, m;
vector<Point> vec;
struct Segment_Tree{
	int rev[N<<2];
	Point mx[N<<2], mn[N<<2];
	inline Point merge(Point A, Point B, int flag){
		Point C; C.sum = A.sum + B.sum;
		if(flag){
			if(A.sl > A.sum + B.sl) C.sl = A.sl, C.pr = A.pr;
			else  C.sl = A.sum + B.sl, C.pr = B.pr;
			if(B.sr > B.sum + A.sr) C.sr = B.sr, C.pl = B.pl;
			else C.sr = B.sum + A.sr, C.pl = A.pl;
			C.ans =  max(A.sr + B.sl, max(A.ans, B.ans));
			if(C.ans == A.ans) C.al = A.al, C.ar = A.ar;
			if(C.ans == B.ans) C.al = B.al, C.ar = B.ar;
			if(C.ans == A.sr + B.sl) C.al = A.pl, C.ar = B.pr;
		}
		else{
			if(A.sl < A.sum + B.sl) C.sl = A.sl, C.pr = A.pr;
			else  C.sl = A.sum + B.sl, C.pr = B.pr;
			if(B.sr < B.sum + A.sr) C.sr = B.sr, C.pl = B.pl;
			else C.sr = B.sum + A.sr, C.pl = A.pl;
			C.ans =  min(A.sr + B.sl, min(A.ans, B.ans));
			if(C.ans == A.ans) C.al = A.al, C.ar = A.ar;
			if(C.ans == B.ans) C.al = B.al, C.ar = B.ar;
			if(C.ans == A.sr + B.sl) C.al = A.pl, C.ar = B.pr;
		}
		return C;
	}
	inline void update(int u){
		mx[u] = merge(mx[lson], mx[rson], 1);
		mn[u] = merge(mn[lson], mn[rson], 0);
	}
	inline void reserve(int u){
		mx[u].sl = -mx[u].sl, mx[u].sr = -mx[u].sr;
		mx[u].sum = -mx[u].sum, mx[u].ans = -mx[u].ans;
		mn[u].sl = -mn[u].sl, mn[u].sr = -mn[u].sr;
		mn[u].sum = -mn[u].sum, mn[u].ans = -mn[u].ans;
	}
	inline void pushdown(int u){
		if(!rev[u]) return; else rev[u] = 0;
		reserve(lson), swap(mn[lson], mx[lson]), rev[lson] ^= 1;
		reserve(rson), swap(mn[rson], mx[rson]), rev[rson] ^= 1;
	}
	inline Point Newnode(int x){
		Point u;
		u.sl = u.sr = u.sum = u.ans = a[x];
		u.pl = u.pr = u.al = u.ar = x; return u;
	}
	inline void build(int u, int l, int r){
		if(l == r) return(void) (mx[u] = mn[u] = Newnode(l));
		int mid = l + r >> 1;
		build(lson, l, mid), build(rson, mid + 1, r), update(u);
	}
	inline void Invert(int u, int l, int r, int L, int R){
		if(l >= L && r <= R){
			reserve(u), swap(mn[u], mx[u]), rev[u] ^= 1;
		}
		else{
			int mid = l + r >> 1;
			if(L <= mid) Invert(lson, l, mid, L, R);
			if(mid < R) Invert(rson, mid + 1, r, L, R); update(u);
		}
	}
	inline void Modify(int u, int l, int r, int pos, int val){
		if(l == r){
			mx[u].ans = val, mx[u].sum = val, mx[u].sl = val, mx[u].sr = val;
			mn[u].ans = val, mn[u].sum = val, mn[u].sl = val, mn[u].sr = val;
		}
		else{
			int mid = l + r >> 1;
			if(pos <= mid) Modify(lson, l, mid, pos, val);
			else Modify(rson, mid + 1, r, pos, val); update(u);
		}
	}
	inline Point query(int u, int l, int r, int L, int R){
		if(l >= L && r <= R) return mx[u];
		int mid = l + r >> 1, flag = 0;  Point left, right;
		if(L <= mid) left = query(lson, l, mid, L, R), flag += 1;
		if(mid < R) right = query(rson, mid + 1, r, L, R), flag += 2;
		if(flag == 1) return left;
		if(flag == 2) return right;
		return merge(left, right, 1);
	}
}van;
int main(){
	read(n);
	for(int i = 1; i <= n; i++) read(a[i]);
	van.build(1, 1, n), read(m);
	while(m--){
		int opt, pos, val, l, r, k;
		read(opt);
		if(opt == 0) read(pos), read(val), van.Modify(1, 1, n, pos, val);
		else{
			read(l), read(r), read(k);
			int ans = 0; vec.clear();
			for(int i = 1; i <= k; i++){
				Point now = van.query(1, 1, n, l, r);
				//cout << now.ans << endl;
				if(now.ans <= 0) break;
				van.Invert(1, 1, n, now.al, now.ar);
				ans += now.ans, vec.push_back(now);
			}
			printf("%d\n", ans);
			for(int i = 0; i < vec.size(); i++)
				van.Invert(1, 1, n, vec[i].al, vec[i].ar);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Mem(a, b) memset((a), sizeof((a)), (b))
#define INF (0x7f7f7f7f)
#define N (200005)
#define lson (u << 1)
#define rson (u << 1 | 1)
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
	int f = 0, ch = 0; x = 0;
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
	for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
	if(f) x = -x;
}
struct Point{
	int sl, pl, sr, pr, ans, al, ar, sum;
	inline Point() { sl = pl = sr = pr = ans = ar = sum = 0; }
};
int a[N], n, m;
vector<Point> vec;
struct Segment_Tree{
	int rev[N<<2];
	Point mx[N<<2], mn[N<<2];
	inline Point merge(Point A, Point B, int flag){
		Point C; C.sum = A.sum + B.sum;
		if(flag){
			if(A.sl > A.sum + B.sl) C.sl = A.sl, C.pr = A.pr;
			else  C.sl = A.sum + B.sl, C.pr = B.pr;
			if(B.sr > B.sum + A.sr) C.sr = B.sr, C.pl = B.pl;
			else C.sr = B.sum + A.sr, C.pl = A.pl;
			C.ans =  max(A.sr + B.sl, max(A.ans, B.ans));
			if(C.ans == A.ans) C.al = A.al, C.ar = A.ar;
			if(C.ans == B.ans) C.al = B.al, C.ar = B.ar;
			if(C.ans == A.sr + B.sl) C.al = A.pl, C.ar = B.pr;
		}
		else{
			if(A.sl < A.sum + B.sl) C.sl = A.sl, C.pr = A.pr;
			else  C.sl = A.sum + B.sl, C.pr = B.pr;
			if(B.sr < B.sum + A.sr) C.sr = B.sr, C.pl = B.pl;
			else C.sr = B.sum + A.sr, C.pl = A.pl;
			C.ans =  min(A.sr + B.sl, min(A.ans, B.ans));
			if(C.ans == A.ans) C.al = A.al, C.ar = A.ar;
			if(C.ans == B.ans) C.al = B.al, C.ar = B.ar;
			if(C.ans == A.sr + B.sl) C.al = A.pl, C.ar = B.pr;
		}
		return C;
	}
	inline void update(int u){
		mx[u] = merge(mx[lson], mx[rson], 1);
		mn[u] = merge(mn[lson], mn[rson], 0);
	}
	inline void reserve(int u){
		mx[u].sl = -mx[u].sl, mx[u].sr = -mx[u].sr;
		mx[u].sum = -mx[u].sum, mx[u].ans = -mx[u].ans;
		mn[u].sl = -mn[u].sl, mn[u].sr = -mn[u].sr;
		mn[u].sum = -mn[u].sum, mn[u].ans = -mn[u].ans;
	}
	inline void pushdown(int u){
		if(!rev[u]) return; else rev[u] = 0;
		reserve(lson), swap(mn[lson], mx[lson]), rev[lson] ^= 1;
		reserve(rson), swap(mn[rson], mx[rson]), rev[rson] ^= 1;
	}
	inline Point Newnode(int x){
		Point u;
		u.sl = u.sr = u.sum = u.ans = a[x];
		u.pl = u.pr = u.al = u.ar = x; return u;
	}
	inline void build(int u, int l, int r){
		if(l == r) return(void) (mx[u] = mn[u] = Newnode(l));
		int mid = l + r >> 1;
		build(lson, l, mid), build(rson, mid + 1, r), update(u);
	}
	inline void Invert(int u, int l, int r, int L, int R){
		if(l >= L && r <= R){
			reserve(u), swap(mn[u], mx[u]), rev[u] ^= 1;
		}
		else{
			int mid = l + r >> 1; pushdown(u);
			if(L <= mid) Invert(lson, l, mid, L, R);
			if(mid < R) Invert(rson, mid + 1, r, L, R); update(u);
		}
	}
	inline void Modify(int u, int l, int r, int pos, int val){
		if(l == r){
			mx[u].ans = val, mx[u].sum = val, mx[u].sl = val, mx[u].sr = val;
			mn[u].ans = val, mn[u].sum = val, mn[u].sl = val, mn[u].sr = val;
		}
		else{
			int mid = l + r >> 1; pushdown(u);
			if(pos <= mid) Modify(lson, l, mid, pos, val);
			else Modify(rson, mid + 1, r, pos, val); update(u);
		}
	}
	inline Point query(int u, int l, int r, int L, int R){
		if(l >= L && r <= R) return mx[u];
		pushdown(u);
		int mid = l + r >> 1, flag = 0;  Point left, right;
		if(L <= mid) left = query(lson, l, mid, L, R), flag += 1;
		if(mid < R) right = query(rson, mid + 1, r, L, R), flag += 2;
		if(flag == 1) return left;
		if(flag == 2) return right;
		return merge(left, right, 1);
	}
}van;
int main(){
	read(n);
	for(int i = 1; i <= n; i++) read(a[i]);
	van.build(1, 1, n), read(m);
	while(m--){
		int opt, pos, val, l, r, k;
		read(opt);
		if(opt == 0) read(pos), read(val), van.Modify(1, 1, n, pos, val);
		else{
			read(l), read(r), read(k);
			int ans = 0; vec.clear();
			for(int i = 1; i <= k; i++){
				Point now = van.query(1, 1, n, l, r);
				//cout << now.ans << ' ' << now.al << ' ' << now.ar << ' ' << endl;
				if(now.ans <= 0) break;
				van.Invert(1, 1, n, now.al, now.ar);
				ans += now.ans, vec.push_back(now);
			}
			printf("%d\n", ans);
			for(int i = 0; i < vec.size(); i++)
				van.Invert(1, 1, n, vec[i].al, vec[i].ar);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Mem(a, b) memset((a), sizeof((a)), (b))
#define INF (0x7f7f7f7f)
#define N (200005)
#define lson (u << 1)
#define rson (u << 1 | 1)
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
	int f = 0, ch = 0; x = 0;
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
	for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
	if(f) x = -x;
}
struct Point{
	int sl, pl, sr, pr, ans, al, ar, sum;
	inline Point() { sl = pl = sr = pr = ans = ar = sum = 0; }
};
int a[N], n, m;
vector<Point> vec;
struct Segment_Tree{
	int rev[N<<2];
	Point mx[N<<2], mn[N<<2];
	inline Point merge(Point A, Point B, int flag){
		Point C; C.sum = A.sum + B.sum;
		if(flag){
			if(A.sl > A.sum + B.sl) C.sl = A.sl, C.pr = A.pr;
			else  C.sl = A.sum + B.sl, C.pr = B.pr;
			if(B.sr > B.sum + A.sr) C.sr = B.sr, C.pl = B.pl;
			else C.sr = B.sum + A.sr, C.pl = A.pl;
			C.ans =  max(A.sr + B.sl, max(A.ans, B.ans));
			if(C.ans == A.ans) C.al = A.al, C.ar = A.ar;
			if(C.ans == B.ans) C.al = B.al, C.ar = B.ar;
			if(C.ans == A.sr + B.sl) C.al = A.pl, C.ar = B.pr;
		}
		else{
			if(A.sl < A.sum + B.sl) C.sl = A.sl, C.pr = A.pr;
			else  C.sl = A.sum + B.sl, C.pr = B.pr;
			if(B.sr < B.sum + A.sr) C.sr = B.sr, C.pl = B.pl;
			else C.sr = B.sum + A.sr, C.pl = A.pl;
			C.ans =  min(A.sr + B.sl, min(A.ans, B.ans));
			if(C.ans == A.ans) C.al = A.al, C.ar = A.ar;
			if(C.ans == B.ans) C.al = B.al, C.ar = B.ar;
			if(C.ans == A.sr + B.sl) C.al = A.pl, C.ar = B.pr;
		}
		return C;
	}
	inline void update(int u){
		mx[u] = merge(mx[lson], mx[rson], 1);
		mn[u] = merge(mn[lson], mn[rson], 0);
	}
	inline void reserve(int u){
		mx[u].sl = -mx[u].sl, mx[u].sr = -mx[u].sr;
		mx[u].sum = -mx[u].sum, mx[u].ans = -mx[u].ans;
		mn[u].sl = -mn[u].sl, mn[u].sr = -mn[u].sr;
		mn[u].sum = -mn[u].sum, mn[u].ans = -mn[u].ans;
	}
	inline void pushdown(int u){
		if(!rev[u]) return; else rev[u] = 0;
		reserve(lson), swap(mn[lson], mx[lson]), rev[lson] ^= 1;
		reserve(rson), swap(mn[rson], mx[rson]), rev[rson] ^= 1;
	}
	inline Point Newnode(int x){
		Point u;
		u.sl = u.sr = u.sum = u.ans = a[x];
		u.pl = u.pr = u.al = u.ar = x; return u;
	}
	inline void build(int u, int l, int r){
		if(l == r) return(void) (mx[u] = mn[u] = Newnode(l));
		int mid = l + r >> 1;
		build(lson, l, mid), build(rson, mid + 1, r), update(u);
	}
	inline void Invert(int u, int l, int r, int L, int R){
		if(l >= L && r <= R){
			reserve(u), swap(mn[u], mx[u]), rev[u] ^= 1;
		}
		else{
			int mid = l + r >> 1;
			if(L <= mid) Invert(lson, l, mid, L, R);
			if(mid < R) Invert(rson, mid + 1, r, L, R); update(u);
		}
	}
	inline void Modify(int u, int l, int r, int pos, int val){
		if(l == r){
			mx[u].ans = val, mx[u].sum = val, mx[u].sl = val, mx[u].sr = val;
			mn[u].ans = val, mn[u].sum = val, mn[u].sl = val, mn[u].sr = val;
		}
		else{
			int mid = l + r >> 1;
			if(pos <= mid) Modify(lson, l, mid, pos, val);
			else Modify(rson, mid + 1, r, pos, val); update(u);
		}
	}
	inline Point query(int u, int l, int r, int L, int R){
		if(l >= L && r <= R) return mx[u];
		int mid = l + r >> 1, flag = 0;  Point left, right;
		if(L <= mid) left = query(lson, l, mid, L, R), flag += 1;
		if(mid < R) right = query(rson, mid + 1, r, L, R), flag += 2;
		if(flag == 1) return left;
		if(flag == 2) return right;
		return merge(left, right, 1);
	}
}van;
int main(){
	read(n);
	for(int i = 1; i <= n; i++) read(a[i]);
	van.build(1, 1, n), read(m);
	while(m--){
		int opt, pos, val, l, r, k;
		read(opt);
		if(opt == 0) read(pos), read(val), van.Modify(1, 1, n, pos, val);
		else{
			read(l), read(r), read(k);
			int ans = 0; vec.clear();
			for(int i = 1; i <= k; i++){
				Point now = van.query(1, 1, n, l, r);
				//cout << now.ans << endl;
				if(now.ans <= 0) break;
				van.Invert(1, 1, n, now.al, now.ar);
				ans += now.ans, vec.push_back(now);
			}
			printf("%d\n", ans);
			for(int i = 0; i < vec.size(); i++)
				van.Invert(1, 1, n, vec[i].al, vec[i].ar);
		}
	}
	return 0;
}