Cod sursa(job #2970322)

Utilizator LucaT2Tasadan Luca LucaT2 Data 24 ianuarie 2023 21:39:41
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.59 kb

#include <fstream>
#include <cstdint>

using namespace std;

ifstream cin("aib.in");
ofstream cout("aib.out");

struct Node {
    int64_t value;
    int left_bound, right_bound;
    Node *left_child, *right_child;
};

Node* create_node(int left_bound, int right_bound) {
    Node *q = new Node;
    q->left_bound = left_bound;
    q->right_bound = right_bound;
    int x;
    if (right_bound == left_bound) {
        cin >> x;
        q->value = x;
        q->left_child = nullptr;
        q->right_child = nullptr;
        return q;
    }
    int mid = (left_bound + right_bound) / 2;
    q->left_child = create_node(left_bound, mid);
    q->right_child = create_node(mid + 1, right_bound);
    q->value = q->left_child->value + q->right_child->value;
    return q;
}

void free_node(Node *r) {
    if (r == nullptr) {
        return;
    }
    free_node(r->left_child);
    free_node(r->right_child);
    delete r;
}

void update(Node *r, int pos, int val) {
    if (pos < r->left_bound || pos > r->right_bound) {
        return;
    }
    if (r->left_bound == r->right_bound) {
        r->value = val + r->value;
        return;
    }
    update(r->left_child, pos, val);
    update(r->right_child, pos, val);
    r->value = r->left_child->value + r->right_child->value;
}

int64_t query(Node *r, int a, int b) {
    if (r->right_bound < a || r->left_bound > b) {
        return 0;
    }
    if (r->left_bound >= a && r->right_bound <= b) {
        return r->value;
    }
    int64_t s1 = query(r->left_child, a, b);
    int64_t s2 = query(r->right_child, a, b);
    return s1 + s2;
}

int main() {
    int n, m;
    cin >> n >> m;
    int c, x, y, z;
    Node *q = create_node(1, n);
    for (int i = 1; i <= m; i++) {
        cin >> c;
        if (c == 0 || c == 1) {
            cin >> x >> y;
        } else if (c == 2) {
            cin >> z;
        }
        if (c == 0) {
            update(q, x, y);
        }
        if (c == 1) {
            cout << query(q, x, y) << "\n";
        }
    if (c == 2) {
        int st = 1, dr = n, pos = -1;
        if (z > query(q, 1, n)) {
            cout << -1 << "\n";
            }
        else {
            while (st <= dr) {
                int mid = st + (dr - st) / 2;
                if (z > query(q, 1, mid)) {
                st = mid + 1;
                }
                else {
                    dr = mid - 1;
                    pos = mid;
                    }
                }
            cout << pos << "\n";
            }
        }
    }
    free_node(q);
    return 0;
    }