Cod sursa(job #641457)

Utilizator Teodor94Teodor Plop Teodor94 Data 28 noiembrie 2011 15:51:55
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include<cstdio>

const int N = 100002;

int n, m, a[N], aib[N], max;

void citire() {
    scanf("%d%d", &n, &m);

    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
}

inline int put2(int x) {
    return x ^ (x & (x - 1));
}

void init() {
    for (int i = 1; i <= n; ++i) {
        aib[i] += a[i];

        if (i + put2(i) <= n)
            aib[i + put2(i)] += aib[i];
    }
}

void update(int pos, int val) {
    while (pos <= n) {
        aib[pos] += val;
        pos += put2(pos);
    }
}

int query(int pos) {
    int sum = 0;

    while (pos > 0) {
        sum += aib[pos];
        pos -= put2(pos);
    }

    return sum;
}

int ask(int x1, int x2) {
    return query(x2) - query(x1 - 1);
}

int query2(int a) {
    if (a <= 0) return -1;

    int pos = max, incep = 0;

    while (pos) {
        if (incep + pos <= n && aib[incep + pos] <= a) {
            a -= aib[incep + pos];
            incep += pos;
        }

        pos >>= 1;
    }

    if (a == 0)
        return incep;

    return -1;
}

inline int maxput2(int x) {
    int a = 1;
    while (a <= x)
        a <<= 1;

    return a >> 1;
}

void rez() {
    max = maxput2(n);
    int tip, a, b;
    for (int i = 1; i <= m; ++i) {
        scanf("%d", &tip);

        if (tip == 0) {
            scanf("%d%d", &a, &b);
            update(a, b);
            continue;
        }

        if (tip == 1) {
            scanf("%d%d", &a, &b);
            printf("%d\n", ask(a, b));
            continue;
        }

        scanf("%d", &a);
        printf("%d\n", query2(a));
    }
}

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

    citire();

    init();

    rez();

    return 0;
}