Cod sursa(job #2328937)

Utilizator vlad.ulmeanu30Ulmeanu Vlad vlad.ulmeanu30 Data 26 ianuarie 2019 11:33:52
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include <bits/stdc++.h>
#define maxn 100000
#define maxl2 17
#define fi first
#define se second
#define DIM 1000000

using namespace std;

FILE *fin, *fout;
int v[maxn+5];
int aint[maxn*maxl2+5];
char BUFF[DIM+5];
int ans, k;

void _reset ()
{
  if ( k == DIM )
  {
    fread ( BUFF, 1, DIM, fin );
    k = 0;
  }
}

int _read ()
{
  int nr = 0;
  while ( BUFF[k] < '0' || BUFF[k] > '9' )
  {
    k++;
    _reset ();
  }
  while ( BUFF[k] >= '0' && BUFF[k] <= '9' )
  {
    nr = nr * 10 + BUFF[k] - '0';
    k++;
    _reset ();
  }
  return nr;
}

void build ( int p, pair<int,int> itv )
{
  aint[p] = 0;
  if ( itv.fi == itv.se )
    aint[p] = v[itv.fi];
  else if ( itv.fi < itv.se )
  {
    int mid = (itv.fi + itv.se) / 2;
    build ( p*2, {itv.fi,mid} );
    build ( p*2+1, {mid+1,itv.se} );
    aint[p] = aint[p*2] + aint[p*2+1];
  }
}

void update ( int p, pair<int,int> itv, int poz )
{
  if ( poz < itv.fi || poz > itv.se ) return;

  if ( itv.fi == itv.se && itv.fi == poz )
    aint[p] = v[poz];
  else if ( itv.fi < itv.se )
  {
    int mid = (itv.fi + itv.se) / 2;
    update ( p*2, {itv.fi, mid}, poz );
    update ( p*2+1, {mid+1,itv.se}, poz );
    aint[p] = aint[p*2] + aint[p*2+1];
  }
}

void query ( int p, pair<int,int> itv, pair<int,int> ok )
{
  if ( itv.se < ok.fi || ok.se < itv.fi ) return;

  if ( itv.fi >= ok.fi && itv.se <= ok.se )
    ans += aint[p];
  else if ( itv.fi < itv.se )
  {
    int mid = (itv.fi + itv.se) / 2;
    query ( p*2, {itv.fi, mid}, ok);
    query ( p*2+1, {mid+1,itv.se}, ok );
  }
}

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

  int n, t;
  n = _read (); t = _read ();

  int i;
  for ( i = 1; i <= n; i++ )
    v[i] = _read ();

  build ( 1, {1,n} );

  int id, a, b, pas, fd;
  while (t--)
  {
    id = _read ();
    if ( id == 0 )
    {
      a = _read (); b = _read ();
      v[a] += b;
      update ( 1, {1,n}, a );
    }
    else if ( id == 1 )
    {
      a = _read (); b = _read ();
      ans = 0;
      query ( 1, {1,n}, {a,b} );
      fprintf ( fout, "%d\n", ans );
    }
    else
    {
      a = _read ();
      for ( fd = 0, pas = (1<<30), i = 0; pas > 0; pas /= 2 )
      {
        ans = 0; query ( 1, {1,n}, {1,i+pas} );
        if ( i + pas <= n && ans <= a )
        {
          i += pas;
          if ( ans == a )
            fd = 1;
        }
      }

      if ( fd == 0 ) i = -1;
      fprintf ( fout, "%d\n", i );
    }
  }

  fclose ( fin );
  fclose ( fout );

  return 0;
}