Cod sursa(job #2970333)

Utilizator LucaT2Tasadan Luca LucaT2 Data 24 ianuarie 2023 21:55:54
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.36 kb
#include <fstream>

using namespace std;

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

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

class SegmentTree {
public:
    SegmentTree(int n) {
        size = n;
        pool = new node[n * 4];
        root = build(1, n);
    }

    ~SegmentTree() {
        delete[] pool;
    }

    void update(int pos, int val) {
        update(root, pos, val);
    }

    int query(int left, int right) {
        return query(root, left, right);
    }

    int find_position(int value) {
        int st = 1, dr = size, pos = -1;
        if (value > query(1, size)) {
            return -1;
        }
        while (st <= dr) {
            int mid = st + (dr - st) / 2;
            if (value > query(1, mid)) {
                st = mid + 1;
            } else {
                dr = mid - 1;
                pos = mid;
            }
        }
        return pos;
    }

private:
    node* build(int left, int right) {
        node* cur = pool++;
        cur->left_bound = left;
        cur->right_bound = right;
        if (left == right) {
            int x;
            cin >> x;
            cur->value = x;
            cur->left_child = cur->right_child = nullptr;
            return cur;
        }
        int mid = (left + right) / 2;
        cur->left_child = build(left, mid);
        cur->right_child = build(mid + 1, right);
        cur->value = cur->left_child->value + cur->right_child->value;
        return cur;
    }

    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;
    }

    int 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;
        }
        int s1 = query(r->left_child, a, b);
        int s2 = query(r->right_child, a, b);
        return s1 + s2;
    }

    node *root;
    node *pool;
    int size;
};

int main() {
    int n, m;
    cin >> n;
    cin >> m;
    SegmentTree st(n);
    for (int i = 1; i <= m; i++) {
        int c;
        cin >> c;
        if (c == 0) {
            int a, b;
            cin >> a >> b;
            st.update(a, b);
        }
        if(c==1) {
        int a, b;
        cin >> a >> b;
        int sum = st.query(a, b);
        cout << sum << endl;
        }
            if(c==2) {
        int a;
        cin >> a;
        int total_sum = st.query(1,n);
        if(a > total_sum) {
            cout << -1 << endl;
        } else {
            int l = 1, r = n;
            int k = -1;
            while(l <= r) {
                int mid = l + (r - l) / 2;
                int sum = st.query(1, mid);
                if(sum >= a) {
                    k = mid;
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
            cout << k << endl;
        }
    }

    }
    return 0;
}