Cod sursa(job #170670)

Utilizator cos_minBondane Cosmin cos_min Data 3 aprilie 2008 00:26:51
Problema Arbori indexati binar Scor Ascuns
Compilator cpp Status done
Runda Marime 2.62 kb
#include <stdio.h>
#include <fstream>
using namespace std;

#define in "aib.in"
#define out "aib3.out"
#define dim 100001

inline int Minim(int a, int b) {
       if ( a < b ) return a;
       return b;
}

int N, M, T;
int Arb[3*dim+66];
int A, B, Sum;
int C, S;

void Update(int,int,int);
void QuerySum(int,int,int);
void QueryInt(int,int);

int main()
{
    memset(Arb,0,sizeof(Arb));
    freopen(in,"r",stdin);
    freopen(out,"w",stdout);
    
    scanf("%d%d", &N, &M);
    for ( int i = 1; i <= N; i++ )
    {
        scanf("%d", &T);
        A = i, B = T;
        Update(1,1,N);
    }
    
    for ( ; M; M-- )
    {
        scanf("%d", &C);
        
        if ( C < 2 )
        {
             scanf("%d%d", &A, &B);
             if ( C == 0 ) Update(1,1,N);
             else
             {
                 S = 0;
                 QuerySum(1,1,N);
                 
                 printf("%d\n", S);
             }
        }
        else
        {
            int pos = N+1;
            int limst=0, limdr=N+1;
            
            scanf("%d", &Sum);
            
            A = 1, B = N;
            S = 0, QuerySum(1,1,N);
            
            if ( S == Sum ) pos = N;
            
            while ( B )
            {
                  B = (limst+limdr)>>1;
                  S = 0, QuerySum(1,1,N);
                  
                  if ( S > Sum )
                  {
                       if ( limdr > B ) limdr = B;
                       B -= 1;
                  }
                  else if ( S == Sum ) pos = Minim(pos,B), limdr = B, B -= 1;
                  else
                  {
                      if ( limst < B ) limst = B;
                      B += 1;
                  }
                  
                  if ( B <= limst ) break;
                  if ( B >= limdr ) break;
            }
            
            if ( pos == N+1 ) printf("-1\n");
            else              printf("%d\n", pos);
        }
    }
}

void Update(int nod, int left, int right)
{
     if ( left == right )
     {
          Arb[nod] += B;
          return;
     }     
     
     int div = (left+right)>>1;
     if ( A <= div ) Update(2*nod,left,div);
     else            Update(2*nod+1,div+1,right);
     
     Arb[nod] = Arb[2*nod] + Arb[2*nod+1];
}

void QuerySum(int nod, int left, int right)
{
     if ( A <= left && right <= B )
     {
          S += Arb[nod];
          return;
     }
     
     int div = (left+right)>>1;
     if ( A <= div ) QuerySum(2*nod, left, div);
     if ( div < B )  QuerySum(2*nod+1,div+1,right);
}