Cod sursa(job #756340)

Utilizator XladhenianGrigorita Vlad-Stefan Xladhenian Data 9 iunie 2012 15:43:26
Problema Arbori indexati binar Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb

#include <fstream>
using namespace std;

long N,M,LL;
long A[100005];
long S[100005];

void ConstruiesteS(void)
{
 long l,a,b,c;
 for (l = 0;(1 << l) <= N;l += 1)
  {
   for (a = (1 << l);a <= N;a += (1 << (l + 1)))
    {
     S[a] += A[a];
     for (b = (l - 1);b >= 0;b -= 1)
      {
       S[a] += S[a - (1 << b)];
      }
    }
   LL = l;
  }
}

void UpdateVal(long a,long b)
{
 while (a <= N)
  {
   S[a] += b;
   a += (a & (-a));
  }
}

long GetSum(long x)
{
 long s = 0;
 while (x > 0)
  {
   s += S[x];
   x -= (x & (-x));
  }
 return s;
}

long GetSum(long a,long b)
{
 return GetSum(b) - GetSum(a - 1);
}

long GetLen(long a)
{
 long tinx;
 long inx = 0;
 long bm = 1 << LL;

 while ((bm != 0) && (inx < N))
  {
   tinx = inx + bm;
   if (S[tinx] == a)
     {
      return tinx;
     }
    else
     {
      if (a > S[tinx])
        {
         inx = tinx;
         a -= S[tinx];
        }
     }
   bm >>= 1;
  }
 if (a == 0)
   {
    return inx;
   }
  else
   {
    return -1;
   }
}

int main(void)
{
 fstream fin("aib.in",ios::in);
 fstream fout("aib.out",ios::out);
 long i,op,a,b;
 fin >> N >> M;
 for (i = 1;i <= N;i += 1)
  {
   fin >> A[i];
  }
 ConstruiesteS();
 for (i = 1;i <= M;i += 1)
  {
   fin >> op;
   switch (op)
    {
     case 0 :
       {
        fin >> a >> b;
        UpdateVal(a,b);
       }
      break;
     case 1 :
       {
        fin >> a >> b;
        fout << GetSum(a,b) << "\n";
       }
      break;
     case 2 :
       {
        fin >> a;
        fout << GetLen(a) << "\n";
       }
      break;
    };
  }
 fin.close();
 fout.close();
 return 0;
}