Cod sursa(job #2273354)

Utilizator vescaDamian-Teodor BELES vesca Data 31 octombrie 2018 14:27:19
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
#include <iostream>
#include <fstream>
#include <vector>

#define cin fin
#define cout fout

using namespace std;

ifstream fin("aib.in");
ofstream fout("aib.out");

int N, M;
vector<int> elements;

struct FenwickTree {
    vector<int> ft;
    int ft_size;

    FenwickTree(int n) {
        ft.resize(n, 0);
        ft_size = n;
    }

    int rsq(int x) {
        int sum = 0;
        for (; x; x -= x & -x) sum += ft[x];
        return sum;
    }

    int rsq(int a, int b) {
        return rsq(b) - (a == 1 ? 0 : rsq(a - 1));
    }

    void adjust(int k, int v) {
        for (; k < ft_size; k += k & -k) ft[k] += v;
    }
};

enum OperationType { ADJUST, RSQ, MINIMUM };

OperationType getOperationTypeFromInt(int x) {
    switch (x) {
        case 0: return OperationType::ADJUST;
        case 1: return OperationType::RSQ;
        default: return OperationType::MINIMUM;
    }
}

struct Operation {
    OperationType type;
    int first, second;
};

vector<Operation> operations;

void Read() {
    cin >> N >> M;
    elements.resize(N + 1);
    operations.resize(M);

    for (int i = 1; i <= N; ++i)
        cin >> elements[i];

    int operationTypeInt;
    for (int i = 0; i < M; ++i) {
        cin >> operationTypeInt;
        operations[i].type = getOperationTypeFromInt(operationTypeInt);

        cin >> operations[i].first;

        if (operationTypeInt != 2)
            cin >> operations[i].second;
    }
}

int lower_bound(FenwickTree &ft, int v) {
    int left = 1, right = ft.ft_size;

    while (left <= right) {
        int middle = left + (right - left) / 2;

        if (ft.rsq(middle) < v)
            left = middle + 1;
        else right = middle - 1;
    }

    if (left == ft.ft_size)
        return -1;
    return left;
}

void Solve() {
    FenwickTree ft(N + 1);
    for (int i = 1; i <= N; ++i)
        ft.adjust(i, elements[i]);

    for (const auto& oper : operations) {
        switch (oper.type) {
        case OperationType::ADJUST: ft.adjust(oper.first, oper.second); break;
        case OperationType::RSQ: cout << ft.rsq(oper.first, oper.second) << "\n"; break;
        case OperationType::MINIMUM: cout << lower_bound(ft, oper.first) << "\n"; break;
        }
    }
}

int main()
{
    Read();
    Solve();
    return 0;
}