Cod sursa(job #116002)

Utilizator scvalexAlexandru Scvortov scvalex Data 17 decembrie 2007 16:34:31
Problema Datorii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.45 kb
#include <iostream>
#include <fstream>

using namespace std;

class Node {
public:
	Node(int _l, int _r, int _v) :
		l(_l),
		r(_r),
		v(_v),
		lchild(0),
		rchild(0),
		parent(0)
	{
	}

	int l, r, v;
	Node *lchild, *rchild, *parent;
};

int N(0),
	M(0);
int A[15001];

Node *root;
Node *lrow[15001];

void build_interval_tree() {
	Node *cur[15001];

	for (int i(1); i <= N; ++i)
		cur[i] = lrow[i] = new Node(i, i, A[i]);

	int lsize = N;

	Node *aux;
	while (true) {
		int k(1);
		for (int i(1); i < lsize; i += 2) {
			aux = new Node(cur[i]->l, cur[i + 1]->r, cur[i]->v + cur[i + 1]->v);
			aux->lchild = cur[i];
			aux->rchild = cur[i + 1];
			aux->l = cur[i]->l;
			aux->r = cur[i + 1]->r;
			cur[i]->parent = aux;
			cur[i + 1]->parent = aux;
			cur[k++] = aux;
		}
		if (lsize % 2 == 1)
			cur[k++] = cur[lsize];
		lsize = k - 1;
		if (lsize == 1) {
			root = cur[1];
			break;
		}
	}

	/************************************************************************/
	/* aux = root;                                                          */
	/* while (aux) {                                                        */
	/*         cout << aux->l << " - " << aux->r << ": " << aux->v << endl; */
	/*         aux = aux->rchild;                                           */
	/* }                                                                    */
	/************************************************************************/
}

int interval_sum(int p, int q, Node *r) {
	if ((p > q) || (0 == r))
		return 0;

	//cout << r->l << " " << r->r << " " << r->v << endl;

	if ((p == r->l) && (q == r->r))
		return r->v;

	if (q <= r->lchild->r) {
		//cout << "To the right!" << endl;
		return interval_sum(p, q, r->lchild);
	} else if (r->rchild->l <= p) {
		//cout << "To the left!" << endl;
		return interval_sum(p, q, r->rchild);
	} else  {
		//cout << "Going through the middle!" << endl;
		return interval_sum(p, r->lchild->r, r->lchild) +
			interval_sum(r->rchild->l, q, r->rchild);
	}
}

int main(int argc, char *argv[]) {
	ifstream fin("datorii.in");
	ofstream fout("datorii.out");
	fin >> N >> M;
	for (int i(1); i <= N; ++i)
		fin >> A[i];

	build_interval_tree();

	int a(0),
		b(0),
		c(0);
	for (int i(0); i < M; ++i) {
		fin >> c >> a >> b;
		if (0 == c) {
			int dif = b;
			Node *n = lrow[a];
			while (n) {
				n->v -= dif;
				n = n->parent;
			}
		} else {
			//cout << "Q " << A << " - " << B << endl;
			fout << interval_sum(a, b, root) << endl;
		}
	}

	fout.close();
	fin.close();

	return 0;
}