#include <bits/stdc++.h>
using namespace std;
// define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int maxN = 3e5 +100;
ll arr[maxN];
struct node {
    int nxt1, nxt2, prv1, prv2;
    ll cnt;
    int l, r;
    ll first, last;
} seg[4 * maxN];
node mergenode(node &node1, node &node2) {
    int l1 = node1.r - node1.l;
    int l2 = node2.r - node2.l;
    node res;
    ll a = node1.last;
    ll b = node2.first;
    res.cnt = node1.cnt + node2.cnt;
    res.nxt1 = node1.nxt1;
    res.nxt2 = node1.nxt2;
    res.prv1 = node2.prv1;
    res.prv2 = node2.prv2;
    res.l = node1.l;
    res.r = node2.r;
    res.first = node1.first;
    res.last = node2.last;
    if (a < b) {
        res.cnt += 1LL * (node1.r - node1.prv1) * (node2.nxt2 - node2.l + 1);
        if (node1.prv1 == node1.l) {
            if (l1 & 1) {
                res.nxt1 = node2.nxt2;
            } else {
                res.nxt2 = node2.nxt2;
            }
        }
        if (node2.nxt2 == node2.r - 1) {
            if (l2 & 1) {
                res.prv2 = node1.prv1;
            } else {
                res.prv1 = node1.prv1;
            }
        }
    } else if (a > b) {
        res.cnt += 1LL * (node1.r - node1.prv2) * (node2.nxt1 - node2.l + 1);
        if (node1.prv2 == node1.l) {
            if (l1 & 1) {
                res.nxt2 = node2.nxt1;
            } else {
                res.nxt1 = node2.nxt1;
            }
        }
        if (node2.nxt1 == node2.r - 1) {
            if (l2 & 1) {
                res.prv1 = node1.prv2;
            } else {
                res.prv2 = node1.prv2;
            }
        }
    }
    return res;
}
void init(int id, int L, int R) {
    if (L + 1 == R) {
        seg[id] = {L, L, L, L, 1, L, R, arr[L], arr[L]};
        return;
    }
    int mid = (L + R) >> 1;
    init(id << 1, L, mid);
    init(id << 1 | 1, mid, R);
    /*cout << seg[id << 1].cnt << " " << seg[id << 1].l << " "
        << seg[id << 1].r << " " << seg[id << 1].prv1 << " " << seg[id << 1].prv2 << endl;
    cout << seg[id << 1 | 1].cnt << " " << seg[id << 1 | 1].l << " " << seg[id << 1 | 1].r << endl;*/
    seg[id] = mergenode(seg[id << 1], seg[id << 1 | 1]);
    /*cout << seg[id].cnt << endl;*/
}
ll lazy[4 * maxN];
bool rev[4 * maxN];
void update_lazy(int id, int L, int R) {
    if (L + 1 < R) {
        int lc = id << 1;
        int rc = id << 1 | 1;
        if (rev[id]) {
            rev[lc] ^= rev[id];
            rev[rc] ^= rev[id];
            lazy[lc] *= -1;
            lazy[rc] *= -1;
        }
        lazy[lc] += lazy[id];
        lazy[rc] += lazy[id];
    }
    if (rev[id]) {
        swap(seg[id].nxt1, seg[id].nxt2);
        swap(seg[id].prv1, seg[id].prv2);
        seg[id].first *= -1;
        seg[id].last *= -1;
        rev[id] = 0;
    }
    if (lazy[id] != 0) {
        seg[id].first += lazy[id];
        seg[id].last += lazy[id];
        lazy[id] = 0;
    }
}
void update(int id, int L, int R, int l, int r, int x) {
    update_lazy(id, L, R);
    if (l == L && r == R) {
        lazy[id] += x;
        update_lazy(id, L, R);
        return;
    }
    int mid = (L + R) >> 1;
    if (l < mid)
        update(id << 1 | 0, L, mid, l, min(mid, r), x);
    if (r > mid)
        update(id << 1 | 1, mid, R, max(l, mid), r, x);
    update_lazy(id << 1 | 0, L, mid);
    update_lazy(id << 1 | 1, mid, R);
    seg[id] = mergenode(seg[id << 1], seg[id << 1 | 1]);
}
void reve(int id, int L, int R, int l, int r) {
    update_lazy(id, L, R);
    if (l == L && r == R) {
        rev[id] = 1;
        update_lazy(id, L, R);
        return;
    }
    int mid = (L + R) >> 1;
    if (l < mid)
        reve(id << 1 | 0, L, mid, l, min(mid, r));
    if (r > mid)
        reve(id << 1 | 1, mid, R, max(l, mid), r);
    update_lazy(id << 1 | 0, L, mid);
    update_lazy(id << 1 | 1, mid, R);
    seg[id] = mergenode(seg[id << 1], seg[id << 1 | 1]);
}
vector<node> nodes;
void get(int id, int L, int R, int l, int r) {
    update_lazy(id, L, R);
    if (l == L && r == R) {
        nodes.push_back(seg[id]);
        return;
    }
    int mid = (L + R) >> 1;
    if (l < mid)
        get(id << 1 | 0, L, mid, l, min(mid, r));
    if (r > mid)
        get(id << 1 | 1, mid, R, max(l, mid), r);
}
int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
    }
    init(1, 1, n + 1);
    for (int i = 0; i < q; i++) {
        char type;
        int l, r;
        cin >> type >> l >> r;
        if (type == '+') {
            int x;
            cin >> x;
            update(1, 1, n + 1, l, r + 1, x);
        } else if (type == '*') {
            reve(1, 1, n + 1, l, r + 1);
        } else {
            nodes.clear();
            get(1, 1, n + 1, l, r + 1);
            node res = nodes[0];
            for (int i = 1; i < nodes.size(); i++) {
                res = mergenode(res, nodes[i]);
            }
            cout << res.cnt << endl;
        }
    }
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |