Cod sursa(job #3246944)

Utilizator BucsMateMate Bucs BucsMate Data 4 octombrie 2024 20:52:04
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <stdlib.h>

using namespace std;

ifstream input("aib.in");
ofstream output("aib.out");

struct Node
{
    Node *child_1;
    Node *child_2;
    Node *parent;
    int sum = 0;
    int left;
    int right;
};

void build_Segment_Tree(Node *curr, vector<int> &numbers)
{
    if(curr->left == curr->right){
        curr->sum = numbers[curr->left];
        return;
    }

    int mid = (curr->left + curr->right)/2;

    curr->child_1 = new Node;
    curr->child_1->parent = curr;
    curr->child_1->left = curr->left;
    curr->child_1->right = mid;
    build_Segment_Tree(curr->child_1, numbers);

    curr->child_2 = new Node;
    curr->child_2->parent = curr;
    curr->child_2->left = mid + 1;
    curr->child_2->right = curr->right;
    build_Segment_Tree(curr->child_2, numbers);

    curr->sum = curr->child_1->sum + curr->child_2->sum;
}

void modify_Segment_Tree(Node *root, int pos, int value)
{
    Node *curr = root;
    while(curr->left != curr->right){
        int mid = (curr->left + curr->right)/2;
        if(pos <= mid){
            curr = curr->child_1;
        }
        else{
            curr = curr->child_2;
        }
    }
    curr->sum += value;

    while(curr != root){
        curr = curr->parent;
        curr->sum += value;
    }
}

void calc_Sum(Node *curr, int a, int b, int &solution)
{
    if(curr->left >= a && curr->right <= b){
        solution += curr->sum;
        return;
    }

    int mid = (curr->left + curr->right)/2;
    if(a <= mid){
        calc_Sum(curr->child_1, a, b, solution);
    }
    if(b >= mid+1){
        calc_Sum(curr->child_2, a, b, solution);
    }
}


int main()
{
    int N, M;
    input >> N >> M;
    vector<int> numbers(N);

    for(int i = 0; i < N; i++){
        input >> numbers[i];
    }

    Node *root = new Node;
    root->left = 0;
    root->right = N-1;
    build_Segment_Tree(root, numbers);

    for(int operation = 0; operation < M; operation++){

        int op, a, b;
        input >> op;

        if(op == 0){
            input >> a >> b;
            a--;
            numbers[a] += b;
            modify_Segment_Tree(root, a, b);
        }

        else if(op == 1){
            input >> a >> b;
            a--;
            b--;
            int solution = 0;
            calc_Sum(root, a, b, solution);
            output << solution << endl;

        }

        else{
            input >> a;
            int left = 0, right = N-1;
            while(left != right){
                int mid = (left + right)/2;
                int solution = 0;
                calc_Sum(root, 0, mid, solution);

                if(solution < a){
                    left = mid+1;
                }
                else{
                    right = mid;
                }
            }
            output << left+1 << endl;

        }
    }
    return 0;
}