Cod sursa(job #3157846)

Utilizator Luka77Anastase Luca George Luka77 Data 16 octombrie 2023 23:19:42
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;

#define Read_Optimizations ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define FOR(n) for(int i = 1; i <= n; ++ i)
#define REP(i, n) for(int idx = i; idx <= n; ++ idx)
#define int long long
#define pb push_back
#define pii pair<int, int>
using ll = long long;
using ci = const int;
using cll = const long long;

/// INPUT / OUTPUT
const string problem = "aib";
ifstream fin(problem + ".in");
ofstream fout(problem + ".out");
/////////////////////////////////////////////////////////////////////

/// STRUCTURES
struct SegTree
{
    int offset;
    vector<int>tree;

    inline int next_power_of_two(int x)
    {
        int p = 1;
        while(p <= x) p<<=1;
        return p;
    }

    SegTree(int n)
    {
        offset = next_power_of_two(n);
        tree.resize(offset * 2, 0);
    }

    inline void update(int pos, int val)
    {
        for(pos = pos + offset - 1; pos > 0; pos >>= 1)
            tree[pos] += val;
    }

    inline int _query(int node, int left, int right, int tree_left, int tree_right)
    {
        if(left >= tree_left && right <= tree_right) return tree[node];

        if(left > tree_right || right < tree_left) return 0;

        int mid = (left + right) >> 1;
        int left_query = _query(node * 2, left, mid, tree_left, tree_right);
        int right_query = _query(node * 2 + 1, mid + 1, right, tree_left, tree_right);

        return left_query + right_query;
    }

    inline int query(int tree_left, int tree_right)
    {
        return _query(1, 1, offset, tree_left, tree_right);
    }

    inline int _binary_search(int node, int left, int right, int tree_left, int x, int &suma)
    {
        if(right < tree_left) return left;

        if(tree[node] + suma < x)
        {
            suma += tree[node];
            return right;
        }

        if(left == right) return left - 1;

        int mid = (left + right) >> 1;
        int query_left = _binary_search(node * 2, left, mid, tree_left, x, suma);

        if(query_left < mid) return query_left;
        else return _binary_search(node * 2 + 1, mid + 1, right, tree_left, x, suma);
    }

    inline int binary_searchg(int x)
    {
        int sum = 0;
        return _binary_search(1, 1, offset, 1, x, sum);
    }
};
/////////////////////////////////////////////////////////////////////

/// GLOBAL VARIABLES
ci NMAX = 1e5 + 5;
int n, m;
SegTree arbint(NMAX);
/////////////////////////////////////////////////////////////////////

/// FUNCTIONS

/////////////////////////////////////////////////////////////////////

/// SOLUTION
signed main()
{
    Read_Optimizations

    fin >> n >> m;

    FOR(n)
    {
        int x; fin >> x;
        arbint.update(i, x);
    }

    FOR(m)
    {
        int type; fin >> type;
        if(type == 0)
        {
            int a, b; fin >> a >> b;
            arbint.update(a, b);
        }
        if(type == 1)
        {
            int a, b; fin >> a >> b;
            fout << arbint.query(a, b) << '\n';
        }
        if(type == 2)
        {
            int a; fin >> a;
            int x = arbint.binary_searchg(a);
            if(arbint.query(1, x + 1) == a)
                fout << x + 1 << '\n';
            else
                fout << -1 << '\n';
        }
    }
}