Cod sursa(job #2003170)

Utilizator radu.bRadu Brumariu radu.b Data 22 iulie 2017 06:47:01
Problema Arbori indexati binar Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 2.33 kb
#include<stdio.h>
#include<stdlib.h>

void update(int *array, int n, int idx, int val);
int query(int *array, int n, int margin);
int search(int *array, int n, int val);
void print_array(int *array, int n);

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

    int N, M;
    scanf("%d", &N);
    scanf("%d", &M);
    int *array = calloc(N+1, sizeof(int));
    if(!array) {
        fprintf(stderr, "failed to allocate memory");
        exit(1);
    }

    for(int i = 1; i <= N; i++) {
        int v;
        scanf("%d", &v);
        update(array, N, i, v);
    }

//    print_array(array, N);
    for(int i = 0; i < M; i++) {
        int op, idx, val;
        scanf("%d", &op);
        switch(op) {
        case 0:
            scanf("%d %d", &idx, &val);
            update(array, N, idx, val);
//            print_array(array, N);
            break;
        case 1:
            scanf("%d %d", &idx, &val);
            printf("%d\n", query(array, N, val) - query(array, N, idx-1));
            break;
        case 2:
            scanf("%d", &val);
//            print_array(array, N);
//            printf("searching for %d\n", val);
            printf("%d\n", search(array, N, val));
            break;
        default:
            break;
        }
    }
    return 0;
}

void update(int *array, int n, int idx, int val) {
    while(idx <= n) {
        array[idx] += val;
        idx += (idx & -idx);
    }
}

int query(int *array, int n, int margin) {
    int sum = 0;
    while(margin > 0 && margin <= n) {
        sum += array[margin];
        margin -= (margin & -margin);
    }
    return sum;
}

int search(int *array, int n, int val) {
    int step=0, idx = 1;
    int ncopy = n;
    while(ncopy >>= 1) {
        step++;
    }
    step = (1 << step) - 1;
//    printf("step: %d\n", step);
    while(step != 0 && idx < n) {
        int tidx = idx + step;
//        printf("[%d] [next: %d] %d : %d\n", idx, tidx, val, array[tidx]);
        if(array[tidx] == val) return tidx;
        else if(val > array[tidx]) {
            idx = tidx;
            val -= array[tidx];
        }
        step >>= 1;
    }
    if(!val) return -1;
//    printf("n: %d, idx: %d\n", n, idx);
    return idx;
}

void print_array(int *array, int n) {
    printf("array: ");
    for( int i = 1; i <= n; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
}