Cod sursa(job #1756715)

Utilizator crushackPopescu Silviu crushack Data 13 septembrie 2016 15:11:28
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <fstream>
#include <vector>

#define zeros(x) ((x) & (x - 1) ^ (x))

using namespace std;

void update(vector<int>& aib, int pos, int val) {
  for (; pos < (int) aib.size(); pos += zeros(pos)) {
    aib[pos] += val;
  }
}

int query(const vector<int>& aib, int pos) {
  int ans = 0;
  for (; pos > 0; pos -= zeros(pos)) {
    ans += aib[pos];
  }
  return ans;
}

int range_sum(const vector<int>& aib, int left, int right) {
  return query(aib, right) - query(aib, left - 1);
}

int get_sum(const vector<int>& aib, int sum) {
  int step;
  int pos = 0;

  if (sum == 0 && aib[1])
    return -1;

  for (step = 1; step < (int) aib.size(); step <<= 1);
  for (; step; step >>= 1)
    if (pos + step < (int) aib.size() && aib[pos + step] <= sum) {
      pos += step;
      sum -= aib[pos];
    }
  return sum == 0 ? pos : -1;
}

int main() {

  ifstream fin("aib.in");
  ofstream fout("aib.out");
  vector<int> aib;
  int n, m;

  fin >> n >> m;
  aib.resize(n + 1);
  for (int i = 1; i <= n; ++i) {
    int val;
    fin >> val;
    update(aib, i, val);
  }

  for (int iter = 0; iter < m; ++iter) {
    int option;
    int a, b;

    fin >> option;
    switch (option) {
      case 0:
        fin >> a >> b;
        update(aib, a, b);
      break;

      case 1:
        fin >> a >> b;
        fout << range_sum(aib, a, b) << "\n";
      break;

      case 2:
        fin >> a;
        fout << get_sum(aib, a) << "\n";
      break;
    }
  }

  return 0;
}