Cod sursa(job #2819155)

Utilizator LuciBBadea Lucian LuciB Data 17 decembrie 2021 22:50:12
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <stdio.h>
using namespace std;

const int NMAX = 1e5;

int aib[NMAX + 1], n, p2;

static inline int lsb(int x) {
    return (x & (-x));
}

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

int sum(int poz) {
    int s = 0;
    while(poz) {
        s += aib[poz];
        poz -= lsb(poz);
    }
    return s;
}

int bs(int val) {
    int poz, step, s;
    step = p2;
    poz = s = 0;
    while(step) {
        if(poz + step <= n && s + aib[poz + step] <= val) {
            s += aib[poz + step];
            poz += step;
        }
        step /= 2;
    }
    if(s != val || poz == 0)
        return -1;
    return poz;
}

int main() {
    int m, op, a, b;
    FILE *fin, *fout;
    
    fin = fopen("aib.in", "r");
    fscanf(fin, "%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        fscanf(fin, "%d", &a);
        update(i, a);
    }
    p2 = 1;
    while(p2 * 2 <= n)
        p2 *= 2;
    
    fout = fopen("aib.out", "w");
    for(int i = 0; i < m; i++) {
        fscanf(fin, "%d", &op);
        switch(op) {
        case 0:
            fscanf(fin, "%d%d", &a, &b);
            update(a, b);
            break;
        
        case 1:
            fscanf(fin, "%d%d", &a, &b);
            fprintf(fout, "%d\n", sum(b) - sum(a - 1));
            break;
        
        default:
            fscanf(fin, "%d", &a);
            fprintf(fout, "%d\n", bs(a));
            break;
        }
    }

    fclose(fin);
    fclose(fout);
    return 0;
}