Cod sursa(job #2150745)

Utilizator preda.andreiPreda Andrei preda.andrei Data 3 martie 2018 19:14:51
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <cstdint>
#include <fstream>
#include <vector>

using namespace std;

class Bit
{
public:
  Bit(int size) : bit_(vector<uint32_t>(size + 1, 0)) {}

  void Add(int node, uint32_t value);

  uint32_t GetSum(int left, int right) const;

  int RightBoundary(uint32_t sum) const;

private:
  static int Lsb(int x) { return x & -x; }

  uint32_t GetSum(int right) const;

  vector<uint32_t> bit_;
};


void Bit::Add(int node, uint32_t value)
{
  while (node < (int)bit_.size()) {
    bit_[node] += value;
    node += Lsb(node);
  }
}

uint32_t Bit::GetSum(int left, int right) const
{
  return GetSum(right) - GetSum(left - 1);
}

int Bit::RightBoundary(uint32_t sum) const
{
  int pos = 0;
  int pow = (1 << 25);

  while (pow > 0) {
    if (pos + pow < (int)bit_.size()) {
      auto curr_sum = GetSum(pos + pow);
      if (curr_sum < sum) {
        pos += pow;
      }
    }
    pow -= 1;
  }
  return pos + 1;
}

uint32_t Bit::GetSum(int right) const
{
  uint32_t sum = 0;
  while (right > 0) {
    sum += bit_[right];
    right -= Lsb(right);
  }
  return sum;
}

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

  int size, queries;
  fin >> size >> queries;

  Bit bit(size);
  for (int i = 1; i <= size; ++i) {
    uint32_t num;
    fin >> num;
    bit.Add(i, num);
  }

  for (int i = 0; i < queries; ++i) {
    int type, pos, left, right;
    uint32_t value;

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