Cod sursa(job #3156566)

Utilizator Dragono63Stanciu Rares Stefan Dragono63 Data 11 octombrie 2023 19:33:16
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.27 kb
#ifndef LOCAL
    #pragma GCC optimize("Ofast")
#endif

#ifdef LOCAL
    #define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
using ll = long long;
using ci = const int;
using cll = const long long;

using namespace std;

/*******************************/
// INPUT / OUTPUT

#ifndef LOCAL
    ifstream in("aib.in");
    ofstream out("aib.out");
    #define cin in
    #define cout out
#endif
/*******************************/
/// GLOBAL DECLARATIONS

int N, M;

struct SegTree
{
    int urm_putere_doi(int n)
    {
        int put = 1;
        while (put < n)
            put <<= 1;
        return put;
    }

    int offset;
    vector <int> data;

    SegTree () {}

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

    void update(int pos, int val)
    {
        data[pos + offset] += val;
        for (pos = (pos + offset) / 2 ; pos ; pos >>= 1)
            data[pos] = data[2 * pos] + data[2 * pos + 1];
    }

    int _query(int node, int l, int r, int ql, int qr)
    {
        if (r < ql || l > qr) return 0;

        if (ql <= l && r <= qr)
            return data[node];
        
        int mid = (l + r) / 2;
        int rasp_st = _query(2 * node, l, mid, ql, qr);
        int rasp_dr = _query(2 * node + 1, mid + 1, r, ql, qr);

        return rasp_st + rasp_dr;
    }

    int query(int l, int r)
    {
        return _query(1, 0, offset - 1, l, r);
    }

    int _cb(int node, int l, int r, int ql, int sum_max, int &suma)
    {
        if (r < ql) return 0;

        if (l <= ql && data[node] + suma <= sum_max)
        {
            suma += data[node];
            return r;
        }

        if (l == r) return l - 1;

        int mid = (l + r) / 2;
        int r_stanga = _cb(2 * node, l, mid, ql, sum_max, suma);

        if (r_stanga < mid)
        {
            return r_stanga;
        }

        return _cb(2 * node + 1, mid + 1, r, ql, sum_max, suma);
    }

    int cb(int l, int sum_max)
    {
        int suma = 0;
        return _cb(1, 0, offset - 1, l, sum_max, suma);
    }
} st;
/*******************************/
/// FUNCTIONS

void ReadInput();
void Solution();
void Output();
/*******************************/
///-------------------------------------
inline void ReadInput()
{
    cin >> N >> M;

    st = SegTree(N);
    int x;
    for (int i = 0 ; i < N ; ++ i)
    {
        cin >> x;
        st.update(i, x);
    }
}
///-------------------------------------
inline void Solution()
{
    int k, tip, a, b;
    while (M --)
    {
        cin >> tip >> a;

        if (tip == 0)
        {
            cin >> b;
            -- a;
            st.update(a, b);
        }

        if (tip == 1)
        {
            cin >> b;
            -- a, --b;
            cout << st.query(a, b) << "\n";
        }

        if (tip == 2)
        {
            k = st.cb(0, a);

            if (st.query(0, k) != a)
                cout << "-1\n";
            else
                cout << k + 1 << "\n";
        }
    }
}
///-------------------------------------
inline void Output()
{

}
///-------------------------------------
int main()
{
    #ifndef LOCAL
        ios::sync_with_stdio(false);
        cin.tie(NULL);
        cout.tie(NULL);
    #endif
    ReadInput();
    Solution();
    Output();
    return 0;
}