Cod sursa(job #2478398)

Utilizator melutMelut Zaid melut Data 21 octombrie 2019 23:49:24
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <assert.h>
#include <cstdio>
#include <fstream>
#include <vector>


using namespace std;


char const *inFile = "aib.in";
char const *outFile = "aib.out";


ofstream Write(outFile);


void Update(
    vector<unsigned> &AIB,
    unsigned const index,
    unsigned const value
) {
    for (unsigned i = index; i < AIB.size(); i += (i ^ (i - 1)) & i) {
        AIB[i] += value;
    }
}


unsigned Compute(
    vector<unsigned> &AIB,
    unsigned const index
) {
    unsigned sum = 0;

    for (unsigned i = index; i > 0;  i -= (i ^ (i - 1)) & i) {
        sum += AIB[i];
    }

    return sum;
}


void Build(
    vector<unsigned> &AIB
) {
    unsigned value;

    for (unsigned i = 1; i < AIB.size(); ++i) {
        assert(scanf("%d", &value) == 1);

        Update(AIB, i, value);
    }
}


unsigned Query1(
    vector<unsigned> &AIB,
    unsigned const left,
    unsigned const right
) {
    return Compute(AIB, right) - Compute(AIB, left - 1);
}


int Query2(
    vector<unsigned> &AIB,
    unsigned const value
) {
    unsigned left = 1;
    unsigned right = AIB.size();
    unsigned mid;
    unsigned computedValue;

    while (left <= right) {
        mid = left + ((right - left) >> 1);

        computedValue = Compute(AIB, mid);

        if (computedValue == value) {
            return mid;
        }
        else if (computedValue < value) {
            left = mid + 1;
        }
        else {
            right = mid - 1;
        }
    }

    return -1;
}


void ReadQueries(
    vector<unsigned> &AIB,
    unsigned const m
) {
    unsigned type;
    unsigned a;
    unsigned b;

    for (unsigned i = 0; i < m; ++i) {
        assert(scanf("%d", &type) == 1);

        if (type == 0) {
            assert(scanf("%d%d", &a, &b) == 2);

            Update(AIB, a, b);
        }
        else if (type == 1) {
            assert(scanf("%d%d", &a, &b) == 2);

            Write << Query1(AIB, a, b) << '\n';
        }
        else {
            assert(scanf("%d", &a) == 1);

            Write << Query2(AIB, a) << '\n';
        }
    }
}


int main() {
    (void) freopen(inFile, "r", stdin);

    unsigned n;
    unsigned m;
    assert(scanf("%d%d", &n, &m) == 2);

    vector<unsigned> AIB(n + 1);

    Build(AIB);

    ReadQueries(AIB, m);

    fclose(stdin);
    Write.close();

    return 0;
}