Cod sursa(job #447124)

Utilizator dcm9000Dinu Cristian Mircea - UPB dcm9000 Data 27 aprilie 2010 19:33:58
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>

using namespace std;

typedef struct
{
    int n;
    int* data;
} Aib;

static inline void aib_add(Aib& aib, int index, int val)
{
    while (index <= aib.n)
    {
        aib.data[index] += val;
        index += (index & -index);
    }
}

static inline int aib_partial(Aib& aib, int index)
{
    int sum = 0;

    while (index)
    {
        sum += aib.data[index];
        index &= (index-1);
    }

    return sum;
}

static inline int aib_search(Aib& aib, int sum)
{
    int top = aib.n;
    int bot = 1;

    while (bot <= top)
    {
        int pivot = (top+bot) >> 1;
        int pivSum = aib_partial(aib, pivot);

        if (pivSum >= sum) top = pivot-1; else bot = pivot+1;
    }

    if ((top < aib.n) && (aib_partial(aib, top+1) == sum)) return top+1;

    return -1;
}

int main()
{
    int n, m;

    ifstream fisIn("aib.in");
    fisIn >> n >> m;

    Aib aib;
    aib.n = n;
    aib.data = new int[n+1];
    memset(aib.data, 0, sizeof(int)*(n+1));

    for (int i=1; i<=n; i++)
    {
        int x;
        fisIn >> x;
        aib_add(aib, i, x);
    }

    ofstream fisOut("aib.out");

    while (m--)
    {
        int op, a, b;

        fisIn >> op >> a;

        switch (op)
        {
            case 0:
                fisIn >> b;
                aib_add(aib, a, b);
                break;
            case 1:
                fisIn >> b;
                fisOut << (aib_partial(aib, b)-aib_partial(aib,a-1)) << '\n';
                break;
            case 2:
                fisOut << aib_search(aib, a) << '\n';
                break;
        }
    }
}