Cod sursa(job #2244335)

Utilizator cosmin.pascaruPascaru Cosmin cosmin.pascaru Data 22 septembrie 2018 16:43:14
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>
#include <vector>
#include <stack>
#include <set>
#include <assert.h>
#include <queue>
#include <chrono>
#include <memory>

using LL = long long;
using ULL = int long long;

const std::string _problemName = "aib";

namespace std {
std::ifstream fin(_problemName + ".in");
std::ofstream fout(_problemName + ".out");
}

 #define USE_FILES

#ifdef USE_FILES
#define cin fin
#define cout fout
#endif

class BinaryIndexedTree {

public:

    BinaryIndexedTree(int size) : tree_(size + 1), size_(size) {}

    void add(int pos, int val) {
        for (; pos <= size_; pos = next(pos)) {
            tree_[pos] += val;
        }
    }

    int prefixSum(int pos) {
        int sum = 0;
        for (; pos > 0; pos = prev(pos)) {
            sum += tree_[pos];
        }
        return sum;
    }

    int search(int prefixSum) {
        int curr = 1;
        while (curr < size_) {
            curr *= 2;
        }

        int posSoFar = 0;

        for (; curr > 0; curr /= 2) {
            if (posSoFar + curr <= size_ && tree_[posSoFar + curr] <= prefixSum) {
                posSoFar += curr;
                prefixSum -= tree_[posSoFar];

                if (prefixSum == 0) {
                    return posSoFar;
                }
            }
        }
        return -1;
    }

private:

    int delta(int node) {
        return (node & (-node));
    }

    int next(int node) {
        return node + delta(node);
    }

    int prev(int node) {
        return node - delta(node);
    }

private:
    std::vector<int> tree_;
    int size_;
};

int main() {

    int n, m;
    std::cin >> n >> m;

    BinaryIndexedTree tree(n);

    for (int i = 1; i <= n; ++i) {
        int x;
        std::cin >> x;
        tree.add(i, x);
    }

    for (int i = 1; i <= m; ++i) {
        int op, a, b;
        std::cin >> op >> a;

        if (op == 2) {
            std::cout << tree.search(a) << '\n';
        }
        else if (op == 1) {
            std::cin >> b;
            std::cout << tree.prefixSum(b) - tree.prefixSum(a - 1) << '\n';
        }
        else {
            std::cin >> b;
            tree.add(a, b);
        }
    }

    return 0;
}