Cod sursa(job #2889838)

Utilizator avtobusAvtobus avtobus Data 13 aprilie 2022 14:16:20
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.33 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;

/*
1-based binary-indexed (fenwick) tree.
positions covered: [1, N]
Aib aib(N);         // initialize
aib.inc(1, x);      // increment value at position 1 by x
aib.inc(N, x);      // increment value at position N by x
aib.prefix_sum(N);  // sum over indices [1,N]
aib.range_sum(l,r); // sum over range [l,r]
aib.single(pos);    // the value in position pos (1-based indexing)
*/
template<typename T>
struct Aib {
  Aib(int n): N{n}, tree{ vector<T>(n+1, 0) } {}
  // TODO: initialize from vector

  void inc(int pos, T val) {
    for(int x = pos; x <= N; x += x&-x) {
      tree[x] += val;
    }
  }

  // value at position pos (1-based indexing)
  T single(int pos) {
    // equivalent to:
    // prefix_sum(pos) - prefix_sum(pos-1)
    // repeatedly eliminating the smallest bit from (pos) and from (pos-1)
    // will meet at: pos - (pos & -pos).
    T res = tree[pos];
    for(int x = pos-1; x > pos - (pos & -pos); x -= x & x) {
      res -= tree[x];
    }
    return res;
  }

  // sum over indices [1,pos]
  T prefix_sum(int pos) {
    T res = 0;
    for(int x = pos; x > 0; x -= x & -x) {
      res += tree[x];
    }
    return res;
  }
  T range_sum(int l, int r) {
    return prefix_sum(r) - prefix_sum(l-1);
  }
  int search(T val) {
    int step = 1;
    while(step < N) step *= 2;
    for(int i = 0; step; step /= 2) {
      if (i + step > N) continue;
      if (tree[i+step] <= val) {
        i += step;
        val -= tree[i];
        if (val == 0) {
          return i;
        }
      }
    }
    return -1;
  }
private:
  int N;
  vector<T> tree;
};

ifstream fin {"aib.in"};
ofstream fout {"aib.out"};


int main(void) {
  // freopen("v5.aib.in", "r", stdin);
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int N, M;
  fin >> N >> M;
  Aib<int> aib(N);
  for(int i = 1; i <= N; ++i) {
    int x;
    fin >> x;
    aib.inc(i,x);
  }
  for(int i = 0; i < M; ++i) {
    int q, a, b;
    fin >> q;
    switch(q) {
    case 0:
      fin >> a >> b;
      aib.inc(a,b);
      break;
    case 1:
      fin >> a >> b;
      fout << aib.range_sum(a, b) << "\n";
      break;
    case 2:
      fin >> a;
      fout << aib.search(a) << "\n";
    }
  }

  return 0;
}