Cod sursa(job #594858)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 9 iunie 2011 23:25:50
Problema Arbori indexati binar Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
#include <iostream>
#include <fstream>

using namespace std;

ifstream fin ("aib.in");
ofstream fout ("aib.out");

long AIB[100005], N, BI[50005], Sum[100005];

void BuildBinaryIndex ()
{
    long i, j, index;
    for (i=1; i<=N; ++i)
    {
        BI[i]=-1;
    }
    for (i=1; i<=N; ++i)
    {
        if (BI[i]==-1)
        {
            BI[i]=0;
            index=1;
            while (index<=i)
            {
                if (i&index==0)
                {
                    BI[i]++;
                    index<<=1;
                }
                else
                {
                    break;
                }
            }
            for (j=i<<1; j<=N; j<<=1)
            {
                BI[j]=BI[j>>1]+1;
            }
        }
    }
}

void Update (long P, long V)
{
    long i=P;
    while (i<=N)
    {
        AIB[i]+=V;
        /*if (i%2==1)
        {
            i++;
        }
        else
        {*/
            i+=(1<<BI[i]);
        //}
    }
}

long Query (long a, long b)
{
    long i, Sa=0, Sb=0;
    i=b;
    while (i>0)
    {
        Sb+=AIB[i];
        /*if (i%2==1)
        {
            i--;
        }
        else
        {*/
            i-=(1<<BI[i]);
        //}
    }
    i=a-1;
    while (i>0)
    {
        Sa+=AIB[i];
        /*if (i%2==1)
        {
            i--;
        }
        else
        {*/
            i-=(1<<BI[i]);
        //}
    }
    return Sb-Sa;
}

long Search(long val)
{
    long i, step;
    for ( step = 1; step < N; step <<= 1 );
    for( i = 0; step; step >>= 1 )
    {
        if( i + step <= N)
        {
            if( val >= AIB[i+step] )
            {
                i += step, val -= AIB[i];
                if ( !val ) return i;
            }
        }
    }
    return -1;
}

int main()
{
    long M, i, OTip, X, Y;
    fin >> N >> M;
    BuildBinaryIndex ();
    for (i=1; i<=N; ++i)
    {
        fin >> X;
        Sum[i]=Sum[i-1]+X;
        Update (i, X);
    }
    for (; M>0; --M)
    {
        fin >> OTip >> X;
        if (OTip==0)
        {
            fin >> Y;
            Update (X, Y);
        }
        if (OTip==1)
        {
            fin >> Y;
            fout << Query (X, Y) << "\n";
        }
        if (OTip==2)
        {
            fout << Search (X) << "\n";
        }
    }
    return 0;
}