Cod sursa(job #1755981)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 11 septembrie 2016 15:59:51
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <algorithm>
#include <string>
#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;

#ifdef INFOARENA
#define TEST 0
#else
#define TEST 1
#endif

class BinaryIndexedTree {
 public:
  BinaryIndexedTree(int num_values) : num_values_(num_values) {
    values_.resize(num_values_ + 1);
  }

  void Update(int pos, int val) {
    while (pos < values_.size()) {
      values_[pos] += val;
      pos += pos & -pos;
    }
  }

  int Query(int pos) {
    int sum = 0;
    while (pos > 0) {
      sum += values_[pos];
      pos -= pos & -pos;
    }
    return sum;
  }

  int Query(int pos_1, int pos_2) {
    if (pos_1 > pos_2) swap(pos_1, pos_2);
    return Query(pos_2) - Query(pos_1 - 1);
  }

  int FindFirstSum(int sum) {
    int left = 1, right = num_values_, middle;
    while (left + 1 < right) {
      middle = (left + right) / 2;
      int query_sum = Query(middle);
      if (query_sum >= sum) {
        right = middle;
      } else {
        left = middle;
      }
    }
    return Query(left) == sum ? left : Query(right) == sum ? right : -1;
  }

 private:
  vector<int> values_;
  int num_values_;
};


int main() {
  freopen("aib.in","r",stdin);
  freopen("aib.out","w",stdout);
  int num_values, num_queries;
  scanf("%d %d", &num_values, &num_queries);
  BinaryIndexedTree *aib = new BinaryIndexedTree(num_values);
  for (int i = 0; i < num_values; ++i) {
    int val;
    scanf("%d", &val);
    aib->Update(i + 1, val);
  }
  for (int i = 0; i < num_queries; ++i) {
    int type, pos, val;
    scanf("%d", &type);
    if (type == 0 || type == 1) {
      scanf("%d %d", &pos, &val);
      if (type == 0) {
        aib->Update(pos, val);
      } else {
        int pos_1 = pos;
        int pos_2 = val;
        printf("%d\n", aib->Query(pos_1, pos_2));
      }
    } else {
      scanf("%d", &val);
      printf("%d\n", aib->FindFirstSum(val));
    }
  }

  return 0;
}