Cod sursa(job #2819657)

Utilizator Alex_HossuHossu Alexandru Alex_Hossu Data 18 decembrie 2021 19:49:18
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <stdio.h>

#define NMAXX 100000
#define LOG_N 16

using namespace std;

int v[NMAXX + 1], aib[NMAXX + 1];

int lastSignificantBit(int x) {
  return x & -x;
}

void build(int n) {
  int i;

  for (i = 1; i <= n; i++) {
    aib[i] += v[i];
    if (i + lastSignificantBit(i) <= n)
      aib[i + lastSignificantBit(i)] += aib[i];
  }
}

void update(int pos, int val, int n) {
  while (pos <= n) {
    aib[pos] += val;
    pos += lastSignificantBit(pos);
  }
}

int query(int x) {
  int rez;

  rez = 0;
  while ( x > 0 ) {
    rez += aib[x];
    x -= lastSignificantBit(x);
  }

  return rez;
}

int search(int val, int n) {
  int pos, step, sum;

  sum = pos = 0;
  step = 1 << LOG_N;
  while (step > 0) {
    if (pos + step <= n && sum + aib[pos + step] <= val) {
      pos += step;
      sum += aib[pos];
    }
    step >>= 1;
  }

  if (sum != val || pos == 0)
    pos = -1;

  return pos;
}

int main() {
  FILE *fin, *fout;
  int n, m, i, cer, a, b;

  fin = fopen("aib.in", "r");
  fout = fopen("aib.out", "w");

  fscanf(fin, "%d%d", &n, &m);
  for (i = 1; i <= n; i++)
    fscanf(fin, "%d", &v[i]);

  build(n);

  for (i = 0; i < m; i++) {
    fscanf(fin, "%d", &cer);

    if (cer == 0) {
      fscanf(fin, "%d%d", &a, &b);
      update(a, b, n);
    } else if (cer == 1) {
      fscanf(fin, "%d%d", &a, &b);
      fprintf(fout, "%d\n", query(b) - query(a - 1));
    } else {
      fscanf(fin, "%d", &a);
      fprintf(fout, "%d\n", search(a, n));
    }
  }

  fclose(fin);
  fclose(fout);

  return 0;
}