Range sums with updates

Keep a list of numbers and answer two kinds of operation:

  • S l r: print a[l] + a[l+1] + ... + a[r];
  • U i v: change a[i] to v.

Positions start at 0. Use a segment tree or a Fenwick tree, so that both operations take O(log n).

What to build

A structure that answers range sums and single changes in O(log n) each.

Requirements

  • Use a segment tree or a Fenwick tree.
  • For U i v, change the stored value and every partial sum that includes it.
  • Use a type that is wide enough for the sums.

Input

A line with n and q (1 ≤ n, q ≤ 1000). A line with the n numbers (each from −1 000 000 to 1 000 000). Then q lines, each S l r (0 ≤ l ≤ r < n) or U i v (0 ≤ i < n, v from −1 000 000 to 1 000 000).

Output

For each S operation, one line with the sum.

Constraints

1 ≤ n, q ≤ 1000, and every value is from −1 000 000 to 1 000 000.

Example

Input:

5 4
1 2 3 4 5
S 0 4
S 1 3
U 2 10
S 1 3

Output:

15
9
16

Why it works

Both trees keep sums of blocks whose sizes are powers of two. Any range is made of about log n such blocks, and one value belongs to about log n of them.

Examples

Example 1 · Input
5 4
1 2 3 4 5
S 0 4
S 1 3
U 2 10
S 1 3
Expected output
15
9
16
Example 2 · Input
1 2
-7
S 0 0
U 0 3
Expected output
-7

Hints

Hint 1

A Fenwick tree is the shortest solution: add(i, delta) climbs with i += i & -i, prefix(i) descends with i -= i & -i. Shift indexes by 1, because it is 1-based.

Hint 2

The sum of a[l..r] is prefix(r + 1) - prefix(l) with 1-based prefix sums.

Hint 3

For U i v, add v - a[i] at position i, then remember a[i] = v. Use long long: sums can pass two billion.

Solution

Show one correct solution (try it yourself first)
#include <stdio.h>

int n;
long long a[1000];
long long bit[1001];

void add(int i, long long delta) {     /* position i (0-based) */
    for (i++; i <= n; i += i & -i) bit[i] += delta;
}

long long prefix(int i) {              /* a[0] + ... + a[i - 1] */
    long long s = 0;
    for (; i > 0; i -= i & -i) s += bit[i];
    return s;
}

int main(void) {
    int q;
    scanf("%d %d", &n, &q);
    for (int i = 0; i < n; i++) {
        scanf("%lld", &a[i]);
        add(i, a[i]);
    }
    for (int k = 0; k < q; k++) {
        char op;
        int x, y;
        scanf(" %c %d %d", &op, &x, &y);
        if (op == 'S') {
            printf("%lld\n", prefix(y + 1) - prefix(x));
        } else {
            add(x, y - a[x]);
            a[x] = y;
        }
    }
    return 0;
}

Lesson: Segment trees and Fenwick trees →