Cod sursa(job #3331086)

Utilizator DariusJohnDarius Dumitrescu DariusJohn Data 24 decembrie 2025 13:32:11
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <bits/stdc++.h>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("aib.in");
ofstream fout("aib.out");
vector<int> tree;
int n;
void update(int pos, int val) {
  while (pos <= n) {
    tree[pos] += val;
    pos += pos & (-pos);
  }
}

int query(int pos) {
  int s = 0;
  while (pos > 0) {
    s += tree[pos];
    pos -= (pos & -pos);
  }
  return s;
}

// Binary Lifting on BIT: O(log N)
// Finds the smallest index 'pos' such that query(pos) == a
int find_k(int a) {
  int pos = 0;
  int current_sum = 0;

  // Find the largest power of 2 less than or equal to n
  int step = 1;
  while ((step << 1) <= n)
    step <<= 1;

  for (; step > 0; step >>= 1) {
    if (pos + step <= n && current_sum + tree[pos + step] <= a) {
      current_sum += tree[pos + step];
      pos += step;
      // Optimization: if we found the exact sum, we can't just stop
      // because there might be zeros later, but for standard BIT
      // problems, the first occurrence is usually what's needed.
    }
  }

  // Check if the sum we found is actually 'a'
  // This assumes the prefix sums are non-decreasing
  if (current_sum == a)
    return pos;
  return -1;
}

int main() {
  int q;
  fin >> n >> q;
  tree.resize(n + 1, 0);
  for (int i = 1; i <= n; i++) {
    int val;
    fin >> val;
    update(i, val);
  }
  for (int i = 0; i < q; i++) {
    int t;
    fin >> t;
    if (t == 0) {
      int a, b;
      fin >> a >> b;
      update(a, b);
    }
    if (t == 1) {
      int a, b, ans;
      fin >> a >> b;
      ans = query(b) - query(a - 1);
      fout << ans << "\n";
    }
    if (t == 2) {
      int a;
      fin >> a;
      fout << find_k(a) << "\n";
    }
  }
}