Cod sursa(job #2680727)

Utilizator cristi_macoveiMacovei Cristian cristi_macovei Data 4 decembrie 2020 00:53:17
Problema Datorii Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <iostream>
#include <fstream>
#include <cassert>

const int NMAX = 15e3;

int n, m;

int a[1 + NMAX];

int seg_tree[3 * NMAX];

void build(int node, int left, int right) {
  if (left == right) {
    seg_tree[node] = a[left];
    return;
  }

  int mid = (left + right) / 2;
  int left_child = node * 2;
  int right_child = node * 2 + 1;

  build(left_child, left, mid);
  build(right_child, mid + 1, right);

  seg_tree[node] = seg_tree[left_child] + seg_tree[right_child];
}

void update(int node, int left, int right, int ind, int val) {
  if (left == right) {
    assert(left == ind);
    seg_tree[node] -= val;
    return;
  }

  int mid = (left + right) / 2;
  int left_child = node * 2;
  int right_child = node * 2 + 1;

  if (mid >= ind)
    update(left_child, left, mid, ind, val);
  else
    update(right_child, mid + 1, right, ind, val);

  seg_tree[node] = seg_tree[left_child] + seg_tree[right_child];
}

int query(int node, int left, int right, int q_left, int q_right) {
  if (right < q_left || left > q_right)
    return 0;

  if (q_left <= left && right <= q_right)
    return seg_tree[node];

  int mid = (left + right) / 2;
  int left_child = node * 2;
  int right_child = node * 2 + 1;

  assert(left != right);
  return query(left_child, left, mid, q_left, q_right) + query(right_child, mid + 1, right, q_left, q_right);
}


int main() {
  std::ifstream in("datorii.in");
  std::ofstream out("datorii.out");

  in >> n >> m;

  for (int i = 1; i <= n; ++i)
    in >> a[i];

  build(1, 1, n);

  int q_type, q_a, q_b;
  for (int i = 1; i <= m; ++i) {
    in >> q_type >> q_a >> q_b;

    if (q_type == 0)
      update(1, 1, n, q_a, q_b);
    else
      out << query(1, 1, n, q_a, q_b) << '\n';
  }

  return 0;
}