Cod sursa(job #1751917)

Utilizator dtoniucDaniel Toniuc dtoniuc Data 2 septembrie 2016 12:39:01
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.44 kb
#include <fstream>
#include <queue>

using namespace std;

int* CreateBit(int n, istream &fin);
void ApplyQuerys(int n, int m, int* tree, istream &fin, ostream &fout);
void ChangeElem(int n, int a, int b, int *tree);
int SumElem(int a, int b, int *tree);
int GetSum(int a, int* tree);
int DetPos(int n, int a, int *tree);

int main()
{
    ifstream fin;
    ofstream fout;
    fout.open("aib.out");
    fin.open("aib.in");

    int n, m;
    fin >> n >> m;

    int* tree = CreateBit(n, fin);

    ApplyQuerys(n, m, tree, fin, fout);

    fin.close();
    fout.close();
    return 0;
}

int* CreateBit(int n, istream &fin)
{
    int *tree = new int[n + 1]();
    int x;

    for(int i = 1; i <= n; i++)
    {
    	fin >> x;

        int r = 0;
        while(((1 << r) & i) == 0)
        {
            r ++;
        }

        tree[i] = SumElem(i - (1 << r) + 1, i - 1, tree) + x;
    }

    return tree;
}

void ApplyQuerys(int n, int m, int* tree, istream &fin, ostream &fout)
{
    int opt, a, b;

    for(int i = 1; i <= m; i++)
    {
        fin >> opt;
        switch(opt)
        {
            case 0:
                fin >> a >> b;
                ChangeElem(n, a, b, tree);
                break;
            case 1:
                fin >> a >> b;
                fout << SumElem(a, b, tree) << '\n';
                break;
            case 2:
                fin >> a;
                if(a == 0)
                	fout << "-1\n";
                else
                	fout << DetPos(n, a, tree) << '\n';
                break;
            default:
                exit(1);
        }
    }
}

void ChangeElem(int n, int a, int b, int *tree)
{
    while(a > 0 && a <= n)
    {
        tree[a] += b;
        a += (a & (-1)*a);
    }
}

int SumElem(int a, int b, int *tree)
{
    return GetSum(b, tree) - GetSum(a - 1, tree);
}

int GetSum(int a, int* tree)
{
    int sum = 0;

    while(a > 0)
    {
        sum += tree[a];
        a -= (a & (-1)*a);
    }

    return sum;
}

int DetPos(int n, int a, int *tree)
{
    int r = 0;

    while((1 << r) <= n)
    {
        r++;
    }
    r--;

    int idx = 0;
    int bitMask = (1 << r);

    while((bitMask != 0) && (idx < n))
    {
        int tmp = idx + bitMask;

        if(a == tree[tmp])
        {
            return tmp;
        }
        else if(a > tree[tmp] && tmp < n)
        {
            idx = tmp;
            a -= tree[tmp];
        }

        bitMask >>= 1;
    }

    if(a != 0)
    {
        return -1;
    }

    return idx;
}