Cod sursa(job #2757971)

Utilizator ptlsebiptl sebi ptlsebi Data 7 iunie 2021 20:26:09
Problema Arbori indexati binar Scor 0
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.22 kb
#include <stdio.h>
#include <stdint.h>

void read_uint32_t(FILE *__restrict stream, uint32_t *__restrict nr) {
    uint8_t ch;
    *nr = 0;
    while ((ch = fgetc(stream)) && ('0' <= ch && ch <= '9')) {
        *nr *= 10;
        *nr += ch - '0';
    }
    if (ch == '\r') {
        fgetc(stream);
    }
}

int32_t __inline__ lsb(int32_t x) {
    return (x) & ~(x - 1);
}

uint32_t aib[100001];

uint32_t n, m;

uint32_t suma(uint32_t p) {
    uint32_t s = 0;
    uint32_t p2;
    while (p) {
        p2 = lsb(p);
        s += aib[p];
        p -= p2;
    }
    return s;
}

void actualizare(uint32_t p, uint32_t val) {
    uint32_t p2;
    while (p <= n) {
        aib[p] += val;
        p2 = lsb(p);
        p += p2;
    }
}

uint32_t search(uint32_t val) {
    uint32_t p = 0;
    uint32_t pas = 1 << 16;
    while (pas) {
        if (p + pas <= n && suma(p + pas) < val) {
            p += pas;
        }
        pas /= 2;
    }
    if (p < n && suma(p + 1) == val) {
        return p + 1;
    }
    return UINT32_MAX;
}

int main() {
    FILE *__restrict in = fopen("aib.in", "r");
    FILE *__restrict out = fopen("aib.out", "w");

    read_uint32_t(in, &n);
    read_uint32_t(in, &m);

    {
        uint32_t i;
        uint32_t x, y;
        for (i = 1; i <= n; ++i) {
            read_uint32_t(in, &x);
            actualizare(i, x);
        }

        uint32_t op;
        uint32_t res;
        for (i = 0; i < m; ++i) {
            read_uint32_t(in, &op);
            switch (op) {
                case 0:
                    read_uint32_t(in, &x);
                    read_uint32_t(in, &y);
                    actualizare(x, y);
                    break;
                case 1:
                    read_uint32_t(in, &x);
                    read_uint32_t(in, &y);
                    fprintf(out, "%u\n", suma(y) - suma(x - 1));
                    break;
                default:
                    read_uint32_t(in, &x);
                    res = search(x);
                    if (res == UINT32_MAX) {
                        fprintf(out, "-1\n");
                    } else {
                        fprintf(out, "%u\n", res);
                    }
                    break;
            }
        }
    }

    fclose(in);
    fclose(out);

    return 0;
}