Cod sursa(job #1275373)

Utilizator smallOneAdina Mateescu smallOne Data 25 noiembrie 2014 02:10:54
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.94 kb
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <ctype.h>
#include <cstring>
#include <string>
#include <ctime>
#include <cassert>
#include <utility>

#define LIM 100005

using namespace std;

int AIB[LIM], x, a, b, n, m, op;

int ultim(int x) {
    return ( (~(x - 1)) & x);
}

void updateAIB(int p, int val) {
    for(int i = p; i <= n; i += ultim(i)) {
        AIB[i] += val;
    }
}

int queryAIB(int pos) {
    int res = 0;
    for(int i = pos; i > 0; i -= ultim(i)) {
        res += AIB[i];
    }
    return res;
}

int findK(int s) {
    int step;

    // gasesc pasul (k) maxim de 2^k care e mai mic ca N.
    for(step = 1; step < n; step <<= 1);

    for(int i = 0; step > 0; step >>=1) {
        int ni = i + step;
        if(ni <= n) {
            if(s >= AIB[ni]) {
                i += step;
                s -= AIB[ni];
                if(!s)
                    return i;
            }
        }
    }

    return -1;
}

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

    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &x);
        updateAIB(i, x);
    }
    for(int i = 0; i < m; i++) {
        scanf("%d", &op);
        if(op == 0) { // pe poz. a vei adauga val b
            scanf("%d %d", &a, &b);
            updateAIB(a, b);
        }
        else if (op == 1) { // se det. suma valorilor din interv. a, b
            scanf("%d %d", &a, &b);
            cout << queryAIB(b) - queryAIB(a - 1) << "\n";
        }
        else { // sa se gaseasca pozitia minima k astfel incat suma sa fie a
            scanf("%d", &a);
            cout << findK(a) << "\n";
        }
    }
	return 0;
}