Cod sursa(job #2629494)

Utilizator RobertLearnsCDragomir Robert. RobertLearnsC Data 21 iunie 2020 11:36:58
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>
using namespace std;
#define NMAX 150005
#define last_bit_of_one (i & (-i))

int tree[NMAX], n, m;

void update(int pos, int val) {
    for(int i = pos; i <= n; i += last_bit_of_one) {
        tree[i] += val;
    }
}

int findSum(int pos) {
    int sum = 0;
    for(int i = pos; i >= 1; i -= last_bit_of_one) {
        sum += tree[i];
    }
    return sum;
}

int findMinK(int sum) {
    int left = 1, right = n, minK = 999999;
    while(left <= right) {
        int middle = (left + right) / 2;
        int one_to_middle = findSum(middle); /// suma intervalului [1, mijloc]
        if(one_to_middle == sum) {
            minK = min(minK, middle);
        }
        if(one_to_middle > sum) {
            right = middle - 1;
        } else {
            left = middle + 1;
        }
    }
    return minK == 999999? -1 : minK;
}

void solve(int op) {
    int a, b;
    if(op == 0) {
        scanf("%d%d", &a, &b);
        update(a, b);
    } else if(op == 1) {
        scanf("%d%d", &a, &b);
        /* deoarece findSum(b) va aduna toate elementele de la 1 la b atunci scoatem de la suma elementele de la 1 la a - 1
        * si astfel vom ramane cu sum[a, b]
        */
        printf("%d\n", findSum(b) - findSum(a - 1));
    } else {
        scanf("%d", &a);
        printf("%d\n", findMinK(a));
    }
}

int main() {
    freopen("aib.in", "r", stdin);
    freopen("aib.out", "w", stdout);

    scanf("%d%d", &n, &m);

    for(int i = 1; i <= n; i++) {
        int x;
        scanf("%d", &x);
        update(i, x);
    }

    for(int i = 1; i <= m; i++) {
        int op;
        scanf("%d", &op);
        solve(op);
    }
    return 0;
}