Cod sursa(job #2816800)

Utilizator Teodor94Teodor Plop Teodor94 Data 12 decembrie 2021 02:57:28
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.99 kb
// AIB
// Search in log^2

#include <stdio.h>

#define UPDATE 0
#define SUM_QUERY 1
#define POS_QUERY 2

#define MAX_N 100000
#define LOG_N 16

int n;
int v[MAX_N + 1];
int aib[MAX_N + 1];

inline int leastSignificantBit(int x) {
  return x & -x;
}

void build() {
  int i;

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

    if (i + leastSignificantBit(i) <= n)
      aib[i + leastSignificantBit(i)] += aib[i];
  }
}

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

int query(int pos) {
  int result;

  result = 0;
  while (pos) {
    result += aib[pos];
    pos -= leastSignificantBit(pos);
  }

  return result;
}

int value(int pos) {
  int result, parent;

  result = aib[pos];
  parent = pos - leastSignificantBit(pos);
  --pos;

  while (pos != parent) {
    result -= aib[pos];
    pos -= leastSignificantBit(pos);
  }

  return result;
}

inline int query(int left, int right) {
  return left == right ? value(left) : query(right) - query(left - 1);
}

int search(int value) {
  int pos, step;

  pos = 0;
  step = 1 << LOG_N;

  while (step) {
    if (pos + step <= n && query(pos + step) <= value)
      pos += step;
    step >>= 1;
  }

  if (pos == 0 || query(pos) != value)
    pos = -1;

  return pos;
}

int main() {
  FILE *fin, *fout;
  fin = fopen("aib.in", "r");
  fout = fopen("aib.out", "w");

  int m, i, type, a, b;

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

  build();

  while (m--) {
    fscanf(fin, "%d", &type);

    if (type == UPDATE) {
      fscanf(fin, "%d%d", &a, &b);
      update(a, b);
    } else if (type == SUM_QUERY) {
      fscanf(fin, "%d%d", &a, &b);
      fprintf(fout, "%d\n", query(a, b));
    } else if (type == POS_QUERY) {
      fscanf(fin, "%d", &a);
      fprintf(fout, "%d\n", search(a));
    }
  }

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