Keep a list of numbers and answer two kinds of operation:
S l r: printa[l] + a[l+1] + ... + a[r];U i v: changea[i]tov.
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
5 4 1 2 3 4 5 S 0 4 S 1 3 U 2 10 S 1 3
15 9 16
1 2 -7 S 0 0 U 0 3
-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;
}