Cod sursa(job #1424462)

Utilizator andreiagAndrei Galusca andreiag Data 24 aprilie 2015 14:31:10
Problema Arbori indexati binar Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include <iostream>
#include <fstream>

using namespace std;
#define I(x) ((x)&(-x))
const int INF = 100000888;
const int Nmax = 100555;

int N, M;
int v[Nmax];
int A[Nmax];

void update(int pos, int inc) {
  v[pos] += inc;
  for (int p = pos; p <= N; p += I(p)) {
    A[p] += inc;
  }
}

int sumto(int pos) { // equivalent to query(1, pos)
  int ret = 0;
  for (int p = pos; p; p -= I(p)) {
    ret += A[p];
  }
  return ret;
}

int query(int l, int h) {
  return sumto(h) - sumto(l-1);
}

int getmin(int a) {
  int x = sumto(N);
  if (x < a)
    return -1;
  else if (x == a)
          return N;
  int l = 1, h = N;
  while (h >= l) {
    int mid = (h+l)/2;
    x = sumto(mid);
    if (x == a)
      return mid;
    if (x < a)
      l = mid+1;
    else if (x > a)
      h = mid-1;
  }
  return -1;
}

int main()
{
  ifstream f ("aib.in");
  ofstream g ("aib.out");
  
  int x, a, b;
  f >> N >> M;
  for (int i = 1; i <= N; i++) {
    f >> x;
    v[i] = x;
    for (int p = i; p <= N; p += I(p)) {
      A[p] += x;
    }
  }
  /*
  for (int i = 1; i <= N; i++)
    cout << A[i] << (i == N ? '\n' : ' ');
  for (int i = 0; i <= N; i++) {
    cout << i << '\t' << sumto(i) << '\n';
  }
  */
  
  while (M--) {
    f >> x;
    switch (x) {
      case 0:
        f >> a >> b;
        update (a, b);
        break;
      case 1:
        f >> a >> b;
        g << query(a, b) << '\n';
        break;
      case 2:
        f >> a;
        g << getmin(a) << '\n';
        break;
    }
  }
  
  return 0;
}