Official

D - Swap and Range Sum Editorial by en_translator


Let \(S=(S_0,S_1,\dots,S_N)\) be the cumulative sums of \(A\). In other words, let \(S_i =A_1 + \dots + A_i\).

Consider what happens to the values of \(S\) when swapping \(A_x\) and \(A_{x+1}\). Obviously, values \(S_i\ (i < x)\) do not change. Moreover, \(A_x + A_{x+1}\) remains the same, so \(S_i\ (i \geq x+1)\) are also invariant. Therefore, only \(S_{x}\) is affected, and the new value can be computed as the sum of \(S_{x-1}\) and \(A_{x}\) (after the swap).

Thus, by managing \(S\) along with \(A\), second-kind queries can be answered by simply evaluating and printing \(S_r - S_{l-1}\), allowing us to solve the problem in \(O(1)\) time per query.

Sample code (C++):

#include <bits/stdc++.h>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, q;
    cin >> n >> q;
    vector<int> a(n), s(n + 1);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        s[i + 1] = s[i] + a[i];
    }
    while (q--) {
        int t;
        cin >> t;
        if (t == 1) {
            int x;
            cin >> x;
            --x;
            swap(a[x], a[x + 1]);
            s[x + 1] = s[x] + a[x];
        } else {
            int l, r;
            cin >> l >> r;
            --l;
            cout << s[r] - s[l] << '\n';
        }
    }
}

posted:
last update: