Cod sursa(job #2941438)

Utilizator Matei_MunteanuMunteanu Matei Ioan Matei_Munteanu Data 17 noiembrie 2022 19:09:47
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.21 kb
#include <bits/stdc++.h>
using namespace std;

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

int n, q;
vector<int> A(100004);

struct BinaryIndexedTree
{
    vector<int> bit;
    void init()
    {
        bit.assign(n + 1, 0);
        for (int i = 1; i <= n; i++)
        {
            add(i, A[i]);
        }
    }

    void add(int idx, int value)
    {
        while (idx <= n)
        {
            bit[idx] += value;
            idx += (idx & (-idx));
        }
    }

    int sum(int idx)
    {
        int total = 0;
        while (idx > 0)
        {
            total += bit[idx];
            idx -= (idx & (-idx));
        }
        return total;
    }

    int range_sum(int left, int right)
    {
        return sum(right) - sum(left - 1);
    }

} BIT;

int Search(int val)
{
    int i, step;

    for (step = 1; step < n; step <<= 1)
        ;

    for (i = 0; step; step >>= 1)
    {
        if (i + step <= n)
        {
            if (val >= BIT.bit[i + step])
            {
                i += step, val -= BIT.bit[i];
                if (!val)
                    return i;
            }
        }
    }

    return -1;
}

int main()
{
    fin >> n;
    fin >> q;
    for (int i = 1; i <= n; i++)
    {
        fin >> A[i];
    }
    BIT.init();
    for (int i = 1; i <= q; i++)
    {
        int tip;
        fin >> tip;
        if (tip == 0)
        {
            int idx, value;
            fin >> idx >> value;
            BIT.add(idx, value);
            A[idx] += value;
        }
        else if (tip == 1)
        {
            int left, right;
            fin >> left >> right;
            fout << BIT.range_sum(left, right) << '\n';
        }
        else
        {
            int sum;
            fin >> sum;
            fout << Search(sum) << '\n';

            // cautare binara a lui Patrascu + observatie de la bit
            // sum(i) = bit[i] + sum(i - putere2max(i))
            // int p = 1;
            // while (p < n)
            // {
            //     p <<= 1;
            // }
            // int j = 0;
            // while (p)
            // {
            //     if ((j + p) <= n && BIT.bit[j + p] <= sum)
            //     {
            //         sum -= BIT.bit[j + p];
            //         j += p;
            //     }
            //     p >>= 1;
            // }
            // if (sum == 0)
            //     fout << j << '\n';
            // else
            //     fout << -1 << '\n';
            // cautare binara normala
            // int left = 1, right = n;
            // int poz = -1;
            // while (left <= right)
            // {
            //     int mij = left + (right - left) / 2;
            //     if (BIT.sum(mij) == sum)
            //     {
            //         poz = mij;
            //         break;
            //     }
            //     else if (BIT.sum(mij) < sum)
            //     {
            //         left = mij + 1;
            //     }
            //     else
            //     {
            //         right = mij - 1;
            //     }
            // }
            // fout << poz << '\n';
        }
    }
    return 0;
}