Cod sursa(job #2836431)

Utilizator mihaipriboimihailucapriboi mihaipriboi Data 20 ianuarie 2022 12:57:35
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
// Mihai Priboi

#include <stdio.h>

#define MAXN 100000
#define LOGN 16

int aib[MAXN + 1];

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

void build_aib( int n ) {
  int i;
  for( i = 1; i <= n; i++ )
    if( i + leastSemnificantBit(i) <= n )
      aib[i + leastSemnificantBit(i)] += aib[i];
}

int query( int pos ) {
  int r;

  r = 0;
  while( pos ) {
    r += aib[pos];
    pos -= leastSemnificantBit(pos);
  }

  return r;
}

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

int query( int a, int b ) {
  return query(b) - query(a - 1);
}

int bs( int x, int n ) {
  int r, pas, s;
  r = s = 0;
  pas = 1 << LOGN;

  while( pas ) {
    if( r + pas <= n && s + aib[r + pas] <= x ) {
      r += pas;
      s += aib[r];
    }
    pas /= 2;
  }

  return s == x && s != 0 ? r : -1;
}

int main() {
  FILE *fin, *fout;
  int n, m, i, a, b, op;
  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", &aib[i] );

  build_aib(n);

  for( i = 0; i < m; i++ ) {
    fscanf( fin, "%d%d", &op, &a );
    switch( op ) {
    case 0:
      fscanf( fin, "%d", &b );
      update(a, b, n);
      break;
    case 1:
      fscanf( fin, "%d", &b );
      fprintf( fout, "%d\n", query(a, b) );
      break;
    case 2:
      fprintf( fout, "%d\n", bs(a, n) );
      break;
    }
  }

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