Cod sursa(job #188357)

Utilizator demonuTeodor Stoenescu demonu Data 8 mai 2008 01:57:31
Problema Datorii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.71 kb
#include <stdio.h>

#define LOG_NMAX    16
#define NMAX (1 << LOG_NMAX)

#define FIN "datorii.in"
#define FOUT "datorii.out"

long int vec[LOG_NMAX][NMAX];
int n, m;
FILE *fin, *fout;

void ReadData() {
    fscanf(fin, "%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        fscanf(fin, "%d", &vec[0][i]);
    }
}

void Preprocess() {
    for (int i = 1; i < LOG_NMAX; ++i) {
        for (int j = 0; j <= (n >> i); ++j) {
            vec[i][j] = vec[i - 1][j << 1] + vec[i - 1][(j << 1) | 1];
        }
    }
}

void Modify(int a, int b) {
    for (int i = 0; i < LOG_NMAX; ++i) {
        vec[i][a] -= b;
        a >>= 1;
    }
}

#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))

int Check(int start, int stop, int level) {
	if (start == stop) {
		return vec[0][start];
	}
	
	int mask = (1 << level) - 1;
	int lstop = min(stop, start | mask);
	int rstart = max(start, stop & ~mask);
	int startindex = start >> level;
	int stopindex = stop >> level;

	
	if (startindex == stopindex) {
		if (((start & mask) == 0) && ((stop & mask) == mask)) {
			return vec[level][startindex];
		}
		return Check(start, stop, level - 1);
	}
	
	return Check(start, lstop, level) + Check(rstart, stop, level);
}

void Query(int a, int b) {
    fprintf(fout, "%d\n", Check(a, b, LOG_NMAX));
}

typedef void (* tFunc)(int, int);
tFunc funcs[] = {Modify, Query};

int main () {
    int op, a, b;
    fin = fopen(FIN, "rt");

    ReadData();
    Preprocess();

    fout = fopen(FOUT, "wt");
    for (int i = 0; i < m; ++i) {
        fscanf(fin, "%d %d %d", &op, &a, &b);
        funcs[op](a, b);
    }
    fclose(fout);
    fclose(fin);

    return 0;
}