Cod sursa(job #2889830)

Utilizator avtobusAvtobus avtobus Data 13 aprilie 2022 13:36:44
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <stdio.h>
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

ifstream fin {"aib.in"};
ofstream fout {"aib.out"};
const int Nmax = 1e5+55;
int aib[Nmax];
int N;

void update(int pos, int val) {
  for(int x = pos; x <= N; x += x&-x) {
    aib[x] += val;
  }
}
int prefix_sum(int pos) { // sum over [1,pos]
  int res = 0;
  for(int x = pos; x > 0; x -= x & -x) {
    res += aib[x];
  }
  return res;
}
int single(int pos) { // TODO: update to use efficient formula
  int res = aib[pos];
  for(int x = pos-1; x > pos - (pos & -pos); x -= x & -x) {
    res -= aib[x];
  }
  return res;
}
int range_sum(int l, int r) { // sum over [l,r]
  return prefix_sum(r) - prefix_sum(l-1);
}

int bsearch(int val) {
  int step = 1;
  while(step < N) step *= 2;

  for(int i = 0; step > 0; step /= 2) {
    if (i + step > N) continue;
    if (aib[i+step] <= val) {
      i += step;
      val -= aib[i];
      if (val == 0) {
        return i;
      }
    }
  }
  return -1;
}

int main(void) {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int M;
  fin >> N >> M;
  fill(aib, aib+N+1, 0);
  for(int i = 1; i <= N; i++) {
    int x;
    fin >> x;
    update(i, x);
  }

  for(int i = 0; i < M; i++) {
    int q, a, b;
    fin >> q;
    if (q == 0) {
      fin >> a >> b;
      update(a, b);
    } else if (q == 1) {
      fin >> a >> b;
      fout << range_sum(a, b) << "\n";
    } else {
      fin >> a;
      fout << bsearch(a) << "\n";
    }
  }

  return 0;
}