Cod sursa(job #3331087)

Utilizator DariusJohnDarius Dumitrescu DariusJohn Data 24 decembrie 2025 13:39:48
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <cstdio>
#include <vector>

using namespace std;

// Folosim FILE* pentru viteza maxima de citire/scriere
FILE *fin = fopen("aib.in", "r");
FILE *fout = fopen("aib.out", "w");

int n, q;
vector<int> tree;

// Update: O(log N)
void update(int pos, int val) {
  for (; pos <= n; pos += pos & -pos) {
    tree[pos] += val;
  }
}

// Query: O(log N)
int query(int pos) {
  int s = 0;
  for (; pos > 0; pos -= pos & -pos) {
    s += tree[pos];
  }
  return s;
}

// Find_k folosind Binary Lifting: O(log N)
int find_k(int target) {
  int pos = 0;
  int current_sum = 0;

  // Calculam cea mai mare putere a lui 2 <= n
  int step = 1;
  while ((step << 1) <= n)
    step <<= 1;

  for (; step > 0; step >>= 1) {
    if (pos + step <= n && current_sum + tree[pos + step] <= target) {
      current_sum += tree[pos + step];
      pos += step;
    }
  }

  if (current_sum == target)
    return pos;
  return -1;
}

int main() {
  if (fscanf(fin, "%d %d", &n, &q) != 2)
    return 0;

  tree.assign(n + 1, 0);

  for (int i = 1; i <= n; i++) {
    int val;
    fscanf(fin, "%d", &val);
    update(i, val);
  }

  while (q--) {
    int t;
    fscanf(fin, "%d", &t);
    if (t == 0) {
      int a, b;
      fscanf(fin, "%d %d", &a, &b);
      update(a, b);
    } else if (t == 1) {
      int a, b;
      fscanf(fin, "%d %d", &a, &b);
      fprintf(fout, "%d\n", query(b) - query(a - 1));
    } else if (t == 2) {
      int a;
      fscanf(fin, "%d", &a);
      fprintf(fout, "%d\n", find_k(a));
    }
  }

  fclose(fin);
  fclose(fout);
  return 0;
}