Cod sursa(job #3364035)

Utilizator TimofeiFilipTimofei Filip Emanuel TimofeiFilip Data 27 august 2026 15:03:50
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.72 kb
#include<bits/stdc++.h>
using namespace std;

typedef long long int ll;
const int NMAX = 1e5 * 4 + 5;
ll aint[NMAX];
ll v[NMAX];


void build(ll node, ll left, ll right) {
    if (left == right) {
        aint[node] = v[left];
        return;
    }
    ll middle = (left + right) / 2;
    build(2 * node, left, middle);
    build(2 * node + 1, middle + 1, right);
    aint[node] = aint[2 * node] + aint[2 * node + 1];
}
void update_recursiv(ll node, ll left, ll right, ll position, ll value) {
    if (left == right) {
        aint[node] += value;
        return;
    }
    ll middle = (left + right) / 2;
    if (position <= middle)
        update_recursiv(2 * node, left, middle, position, value);
    else
        update_recursiv(2 * node + 1, middle + 1, right, position, value);
    aint[node] = aint[2 * node] + aint[2 * node + 1];
}
void update(ll pos, ll val, ll n){
    update_recursiv(1, 1, n, pos, val);
}
ll query_recursiv(ll node, ll left, ll right, ll query_left, ll query_right) {
    //printf("node: %d left: %d right: %d q_left: %d q_r: %d\n", node, left, right, query_left, query_right);
    if (left == query_left && right == query_right)
        return aint[node];
    ll middle = (left + right) / 2;
    if (query_right <= middle)
        return query_recursiv(2 * node, left, middle, query_left, query_right);
    if (query_left > middle)
        return  query_recursiv(2 * node + 1, middle + 1, right, query_left, query_right);
    return query_recursiv(2 * node, left, middle, query_left, middle) + query_recursiv(2 * node + 1, middle + 1, right, middle + 1, query_right);
}
ll query(ll l, ll r, ll n) {
    return query_recursiv(1, 1, n, l, r);
}
ll get_min_position(ll n, ll k) {
    ll left, right;
    left = 1;
    right = n;
    ll result = -1;

    while (left <= right) {
        ll middle = (left + right) / 2;
        ll sum = query(1, middle, n);
        if (sum >= k) {
            result = middle;
            right = middle - 1;
        }
        else left = middle + 1;
    }
    if (result == -1) return result;
    if (query(1, result, n) == k)
        return result;
    return -1;
}
int main() {
    freopen("aib.in", "r", stdin);
    freopen("aib.out", "w", stdout);

    ll n, m; scanf("%lld %lld", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &v[i]);
    build(1, 1, n);
    for (; m > 0; m--) {
        ll op, x, y;
        scanf("%lld", &op);
        if (op == 0) {
            scanf("%lld %lld", &x, &y);
            v[x] += y;
            update(x, y, n);
        }
        else if (op == 1) {
            scanf("%lld %lld", &x, &y);
            printf("%lld\n", query(x, y, n));
        }
        else {
            scanf("%lld", &x);
            printf("%lld\n", get_min_position(n, x));
        }
    }
    return 0;
}