Cod sursa(job #2452978)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 1 septembrie 2019 22:13:17
Problema Arbori indexati binar Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <stdio.h>

#define MAX_N 100000

long long num[MAX_N];

int g( int n ){
  return n & (n + 1);
}

int h( int n ){
  return n | (n + 1);
}

long long prefixSum( int n ){
  long long sum;

  sum = 0;
  while( n >= 0 ){
    sum += num[n];
    n = g(n) - 1;
  }

  return sum;
}

void add( int n, int i, int a ){
  while( i < n ){
    num[i] += a;
    i = h(i);
  }
}

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

  int n, num_q, i, b, task, st, dr, mij, a;
  long long aLL;/* scrie ca a <= 2^31 nu < */

  fscanf(fin, "%d%d", &n, &num_q);
  for( i = 0 ; i < n ; i++ ){
    fscanf(fin, "%d", &a);
    add(n, i, a);
  }

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

    if( task == 0 ){
      fscanf(fin, "%d%d", &a, &b);
      add(n, a - 1, b);
    }else if( task == 1 ){
      fscanf(fin, "%d%d", &a, &b);
      fprintf(fout, "%lld\n", prefixSum(b - 1) - prefixSum(a - 2));
    }else{
      fscanf(fin, "%lld", &aLL);
      st = -1;
      dr = n - 1;
      while( dr - st > 1 ){
        mij = (st + dr) / 2;
        if( prefixSum(mij) < aLL )
          st = mij;
        else
          dr = mij;
      }

      if( prefixSum(dr) != aLL )
        fprintf(fout, "-1\n");
      else
        fprintf(fout, "%d\n", dr + 1);
    }
  }

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