Problem:
Score : 100 points

Problem Statement

You are given an array a_0, a_1, ..., a_{N-1} of length N. Process Q queries of the following types.

0 p x: a_p \gets a_p + x

1 l r: Print \sum_{i = l}^{r - 1}{a_i}.

Constraints

1 \leq N, Q \leq 500,000

0 \leq a_i, x \leq 10^9

0 \leq p < N

0 \leq l_i < r_i \leq N

All values in Input are integer.

Input

Input is given from Standard Input in the following format:

N Q
a_0 a_1 ... a_{N - 1}
\textrm{Query}_0
\textrm{Query}_1
:
\textrm{Query}_{Q - 1}

Output

For each query of the latter type, print the answer.

Sample Input 1

5 5
1 2 3 4 5
1 0 5
1 2 4
0 3 10
1 0 5
1 0 3

Sample Output 1

15
7
25
6

Solution in Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;

fn main() {
    input! {
        n: usize,
        q: usize,
        a: [u64; n],
        query: [(usize, usize, usize); q],
    }
    let mut segtree = SegmentTree::new(&a, std::u64::MIN, |a, b| a + b);
    for (qq, x, y) in query {
        match qq {
            0 => segtree.update_with(x as usize, |v| v + y as u64),
            1 => println!("{}", segtree.query(x, y)),
            _ => unreachable!(),
        }
    }
}
struct SegmentTree<T: Copy> {
    n: usize,            // size of data
    f: fn(T, T) -> T,    // binary operation of the monoid
    e: T,                // identity element of the monoid
    binary_tree: Vec<T>, // 1-indexed binary tree (parent: x/2, left_child: x*2, right_child: x*2+1, sibling: x^1, is_x_left_child: x%2==0, is_x_right_child: x%2==1)
}
impl<T: Copy> SegmentTree<T> {
    /// O(n) # create segment tree (e is identity element for a function f in type T)
    fn new(data: &[T], e: T, f: fn(T, T) -> T) -> Self {
        let (n, binary_tree) = (data.len(), vec![e; 2 * data.len().next_power_of_two()]);
        let segment_tree = SegmentTree {
            n,
            f,
            e,
            binary_tree,
        };
        segment_tree.init(data)
    }

    /// O(n) # init segment tree by given data
    fn init(mut self, data: &[T]) -> Self {
        let leaf_offset = self.leaf_offset();
        for (i, &di) in data.iter().enumerate() {
            self.binary_tree[leaf_offset + i] = di;
        }
        for i in (1..leaf_offset).rev() {
            self.binary_tree[i] = (self.f)(self.binary_tree[i * 2], self.binary_tree[i * 2 + 1]);
        }
        self
    }

    /// O(1) # get beginning index of the segment tree leaf
    fn leaf_offset(&self) -> usize {
        self.n.next_power_of_two()
    }

    /// O(log(n)) # set leaf[k] = x, and update segment tree. (non-recursive)
    fn update_with<U>(&mut self, k: usize, f: U)
    where
        U: Fn(T) -> T,
    {
        let mut current = self.leaf_offset() + k;
        self.binary_tree[current] = f(self.binary_tree[current]);
        while current / 2 > 0 {
            current /= 2;
            self.binary_tree[current] = (self.f)(
                self.binary_tree[current * 2],
                self.binary_tree[current * 2 + 1],
            );
        }
    }

    /// O(log(n)) # calculate f(l, l+1, ..., r-1). note the half interval [l, r). (non-recursive)
    fn query(&self, l: usize, r: usize) -> T {
        let (mut l, mut r) = (self.leaf_offset() + l, self.leaf_offset() + r);
        let mut result = self.e;
        while l < r {
            if l % 2 == 1 {
                result = (self.f)(result, self.binary_tree[l]);
                l += 1; // l is right child, so move to next subtree.
            }
            if r % 2 == 1 {
                result = (self.f)(result, self.binary_tree[r ^ 1]);
            }
            l /= 2;
            r /= 2;
        }
        result
    }
}