Cod sursa(job #2087876)

Utilizator BrandonChris Luntraru Brandon Data 14 decembrie 2017 14:43:53
Problema Datorii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <fstream>
#include <cmath>

using namespace std;

ifstream cin ("datorii.in");
ofstream cout ("datorii.out");

const int MaxN = 15005;
const int MaxM = 100005;

int rgEnd;
int debt[2 * MaxN];
int SegTree[4 * MaxN];

int BuildNode(int &lfVal, int &rgVal) {
  return lfVal + rgVal;
}

void BuildTree(int lf = 1, int rg = rgEnd, int node = 1) {
  if (lf == rg) {
    SegTree[node] = debt[lf];
    return;
  }

  int med = (lf + rg) / 2;
  int lfSon = 2 * node;
  int rgSon = 2 * node + 1;

  BuildTree(lf, med, lfSon);
  BuildTree(med + 1, rg, rgSon);
  SegTree[node] = BuildNode(SegTree[lfSon], SegTree[rgSon]);
}

void Update(int pos, int val, int lf = 1, int rg = rgEnd, int node = 1) {
  if (lf == rg) {
    SegTree[node] -= val;
    return; 
  }

  int med = (lf + rg) / 2;
  int lfSon = 2 * node;
  int rgSon = 2 * node + 1;

  if (pos <= med) {
    Update(pos, val, lf, med, lfSon);
  } else {
    Update(pos, val, med + 1, rg, rgSon);
  }

  SegTree[node] = BuildNode(SegTree[lfSon], SegTree[rgSon]);
}

int Query(int lfQ, int rgQ, int lf = 1, int rg = rgEnd, int node = 1) {
  if (lfQ > rg or rgQ < lf) {
    return 0;
  }

  if (lf >= lfQ and rg <= rgQ) {
    // cout << lf << ' ' << rg << ' ' << SegTree[node] << '\n';
    return SegTree[node];
  }

  int med = (lf + rg) / 2;
  int lfSon = 2 * node;
  int rgSon = 2 * node + 1;

  int lfAns = Query(lfQ, rgQ, lf, med, lfSon);
  int rgAns = Query(lfQ, rgQ, med + 1, rg, rgSon);
  return lfAns + rgAns;
}

inline void CalcRgEnd(int n) {
  rgEnd = log2(n);
  rgEnd += (1 << rgEnd) < n;
  rgEnd = (1 << rgEnd);
}

int main() {
  int n, m;
  cin >> n >> m;
  CalcRgEnd(n);

  for (int i = 1; i <= n; ++i) {
    cin >> debt[i];
  }

  BuildTree();

  for (int i = 1; i <= m; ++i) {
    int type, a, b;
    cin >> type >> a >> b;
    if (type == 0) {
      Update(a, b);
    } else {
      cout << Query(a, b) << '\n';
    }
  }
  return 0;
}