Cod sursa(job #1802855)

Utilizator DanielRusuDaniel Rusu DanielRusu Data 10 noiembrie 2016 18:27:42
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.63 kb
#include <cstdio>

using namespace std;

#define DIM 100005

FILE *fin = fopen("aib.in","r");
FILE *fout = fopen("aib.out","w");

int AIB[DIM], N, M, x, tip, a, b, poz, val;

void Update(int poz, int val);
int Query(int poz);
int bin_search(int x);

int main() {
    fscanf(fin, "%d %d\n", &N, &M);

    for(int i = 1; i <= N; ++i) {
        fscanf(fin, "%d", &x);

        Update(i, x);
    }

    for(int i = 1; i <= M; ++i) {
        fscanf(fin, "%d", &tip);

        if(tip == 0) {
            fscanf(fin,"%d %d\n", &poz, &val);

            Update(poz, val);
        }
        else {
            if(tip == 1) {
                fscanf(fin,"%d %d\n", &a, &b);

                fprintf(fout, "%d\n", Query(b) - Query(a - 1));
            }
            else {
                fscanf(fin,"%d\n", &a);

                fprintf(fout, "%d\n", bin_search(a));
            }
        }
    }

    fclose(fin);
    fclose(fout);

    return 0;
}

void Update(int poz, int val) {
    while(poz <= N) {
        AIB[poz] += val;
        poz += poz & (-poz);
    }
}

int Query(int poz) {
    int ans = 0;

    while(poz) {
        ans += AIB[poz];
        poz -= poz & (-poz);
    }

    return ans;
}

int bin_search(int x) {
    int put = 1;

    while(put <= N) {
        put <<= 1;
    }

    put >>= 1;

    int pos = 0;

    while(put) {
        if(pos + put <= N) {
            if(Query(pos + put) < x) {
                pos += put;
            }
        }

        put >>= 1;
    }

    if(pos < N && Query(pos + 1) == x) {
        return pos + 1;
    }

    return -1;
}