Cod sursa(job #3331089)

Utilizator DariusJohnDarius Dumitrescu DariusJohn Data 24 decembrie 2025 13:50:10
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <bits/stdc++.h>
#include <fstream>
#include <vector>
#define int long long
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;
}

int find_k(int target) {
  int pos = 0;
  int current_sum = 0;

  // 1. Gasim cea mai mare putere a lui 2 care este <= n
  int step = 1;
  while ((step << 1) <= n)
    step <<= 1;

  // 2. Binary lifting pe structura AIB-ului
  for (; step > 0; step >>= 1) {
    if (pos + step <= n && current_sum + tree[pos + step] <= target) {
      current_sum += tree[pos + step];
      pos += step;
    }
  }

  // 3. Verificam daca am gasit exact suma target
  if (current_sum == target)
    return pos;
  return -1;
}

signed 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";
    }
  }
}