Cod sursa(job #2015947)

Utilizator preda.andreiPreda Andrei preda.andrei Data 28 august 2017 10:42:48
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <fstream>
#include <vector>

using namespace std;

class Bit
{
public:
  Bit(size_t size) : bit_(size + 1, 0) {}

  int Size() const { return bit_.size() - 1; }

  void Add(size_t pos, int val);

  int GetSum(size_t pos) const;

  int GetSum(size_t left, size_t right) const
  {
    return GetSum(right) - GetSum(left - 1);
  }

private:
  vector<int> bit_;

  int Lsb(int pos) const { return pos & -pos; }
};

void Bit::Add(size_t pos, int val)
{
  while (pos < bit_.size()) {
    bit_[pos] += val;
    pos += Lsb(pos);
  }
}

int Bit::GetSum(size_t pos) const
{
  int sum = 0;
  while (pos > 0 && pos < bit_.size()) {
    sum += bit_[pos];
    pos -= Lsb(pos);
  }
  return sum;
}

int FindFirstPos(const Bit &bit, int sum)
{
  int pos = 0;
  int power = (1 << 25);

  while (power > 0) {
    if (pos + power <= bit.Size() && bit.GetSum(pos + power) < sum) {
      pos += power;
    }
    power >>= 1;
  }

  if (pos < bit.Size() && bit.GetSum(pos + 1) == sum) {
    return pos + 1;
  }
  return -1;
}

int main()
{
  ifstream fin("aib.in");
  ofstream fout("aib.out");

  int n, ops;
  fin >> n >> ops;

  Bit bit(n);
  for (int i = 1; i <= n; ++i) {
    int val;
    fin >> val;
    bit.Add(i, val);
  }

  while (ops--) {
    int type;
    fin >> type;

    if (type == 0) {
      int pos, val;
      fin >> pos >> val;
      bit.Add(pos, val);
    } else if (type == 1) {
      int left, right;
      fin >> left >> right;
      fout << bit.GetSum(left, right) << "\n";
    } else {
      int sum;
      fin >> sum;
      fout << FindFirstPos(bit, sum) << "\n";
    }
  }
  return 0;
}