Cod sursa(job #3157346)

Utilizator Luka77Anastase Luca George Luka77 Data 15 octombrie 2023 13:31:15
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.51 kb
#include <bits/stdc++.h>
using namespace std;

#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
{
    inline int next_power_of_2(int x)
    {
        int p1 = 1;
        while(p1 <= x) p1 *= 2;
        return p1;
    }

    vector<int>tree;
    int offset;

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

    inline void _update(int node, int st, int dr, int pos, int val)
    {
        if(st == dr)
        {
            tree[node] += val;
            return;
        }
        int mid = (st + dr) >> 1;
        if(pos <= mid)
            _update(node * 2, st, mid, pos, val);
        else
            _update(node * 2 + 1, mid + 1, dr, pos, val);

        tree[node] = tree[node * 2] + tree[node * 2 + 1];
    }

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

    inline int query(int node, int st, int dr, int arb_st, int arb_dr)
    {
        if(st >= arb_st && dr <= arb_dr) return tree[node];

        if(st > arb_dr || dr < arb_st) return 0;

        int mid = (st + dr) >> 1;
        return query(node * 2, st , mid, arb_st, arb_dr) + query(node * 2 + 1, mid + 1, dr, arb_st, arb_dr);

    }

    inline int binary_search(int node, int st, int dr, int arb_st, int x, int &sum)
    {
        if(dr < arb_st) return st;

        if(arb_st <= st && tree[node] + sum < x)
        {
            sum += tree[node];
            return dr;
        }

        if(st == dr || node >= offset)
        {
            return st - 1;
        }

        int mid = (st + dr) >> 1;
        int bs_left = binary_search(node * 2, st, mid, arb_st, x, sum);
        if(bs_left < mid)
        {
            return bs_left;
        }
        else
        {
            return binary_search(node * 2 + 1, mid + 1, dr, arb_st, x, sum);
        }
    }
};
/////////////////////////////////////////////////////////////////////

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

/// FUNCTIONS
inline void debug()
{
    /*
8 6
25 42 8 15 1 55 16 67
0 5 12
2 25
2 90
1 7 7
1 2 8
2 241
    */
    for(int i = 1;  i<= 64; ++ i)
    {
        cout << i << " " << arbint.tree[i] << '\n';
    }
}
/////////////////////////////////////////////////////////////////////

/// SOLUTION
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    fin >> n >> queries;

    for(int i = 1; i <= n; ++ i)
    {
        int x; fin >> x;
        arbint._update(1, 1, n, i, x);
    }

    while(queries--)
    {
        int type; fin >> type;

        if(type == 0)
        {
            int a, b; fin >> a >> b;
            arbint._update(1, 1, n, a, b);
        }
        if(type == 1)
        {
            int a, b; fin >> a >> b;
            fout << arbint.query(1, 1, n, a, b) << '\n';
        }
        if(type == 2)
        {
            int sum = 0;
            int a; fin >> a;
            fout << arbint.binary_search(1, 1, n, 1, a, sum) + 1 << '\n';
        }
    }
}