Cod sursa(job #1480411)

Utilizator stoianmihailStoian Mihail stoianmihail Data 2 septembrie 2015 16:01:34
Problema Arbori indexati binar Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.66 kb
#include <stdio.h>

#define Nadejde 131072

int N, M;
int fen[Nadejde + 1];

/** Adauga "val" pe pozitia "pos". **/
void add(int pos, int val) {
  do {
    fen[pos] += val;
    pos += pos & -pos;
  } while (pos <= Nadejde);
}

/** Afla valoarea de pe pozitia "pos". **/
int value(int pos) {
  int s = fen[pos], parent = --pos & (pos + 1);
  while (pos != parent) {
    s -= fen[pos];
    pos &= pos - 1;
  }
  return s;
}

/** Suma partiala pana la "pos". **/
int pSum(int pos) {
  int s = 0;
  while (pos) {
    s += fen[pos];
    pos &= pos - 1;
  }
  return s;
}

/** Suma intre "begin" si "end". **/
int sum(int begin, int end) {
  return pSum(end) - pSum(begin - 1);
}

/** Cauta binar suma partiala "val". **/
int search(int val) {
  int pos = 0, interval = (Nadejde >> 1);
  while (interval) {
    if (fen[pos + interval] < val) {
      val -= fen[pos + interval];
      pos += interval;
    }
    interval >>= 1;
  }
  return (val == value(pos + 1)) ? pos + 1 : -1;
}

int main(void) {
  int i, b, e, val, pos, task;
  FILE *in = fopen("aib.in", "r");
  FILE *out = fopen("aib.out", "w");

  fscanf(in, "%d %d", &N, &M);
  for (i = 1; i <= N; i++) {
    fscanf(in, "%d\n", &val);
    add(i, val);
  }
  while (M--) {
    fscanf(in, "%d", &task);
    if (!task) {
      fscanf(in, "%d %d", &pos, &val);
      add(pos, val);
    } else if (task == 1) {
      fscanf(in, "%d %d", &b, &e);
      fprintf(out, "%d\n", sum(b, e));
    } else {
      fscanf(in, "%d", &val);
      fprintf(out, "%d\n", search(val));
    }
  }
  fclose(in);
  fclose(out);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}