Cod sursa(job #2901279)

Utilizator widzAndrei-Daniel Tava widz Data 13 mai 2022 15:10:43
Problema Datorii Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.29 kb
#include <fstream>
#include <vector>
using namespace std;

class SumSegmentTree
{
	vector<pair<int, int>> storage;
	int lower_bound, upper_bound;

	void recInsert(int crt_node, int pos, int left, int right, int val)
	{
		if (pos < left || pos >right)
			return;
		if (left == right)
		{
			storage[crt_node].first = val;
			return;
		}
		recInsert(crt_node * 2 + 1, pos, left, (left + right) / 2, val);
		recInsert(crt_node * 2 + 2, pos, (right + left) / 2 + 1, right, val);
	}
	int recRange(int crt_node, int left, int right, int range_l, int range_r)
	{
		if (range_l > right || range_r < left)
			return 0;
		if (range_l <= left && range_r >= right)
			return storage[crt_node].first - storage[crt_node].second;
		return recRange(crt_node * 2 + 1, left, (left + right) / 2, range_l, range_r) +
			recRange(crt_node * 2 + 2, (left + right) / 2 + 1, right, range_l, range_r);
	}
	void recUpdate(int crt_node, int left, int right, int range_l, int range_r, int val)
	{
		if (range_l > right || range_r < left)
			return;
		if (range_l <= left && range_r >= right)
		{
			storage[crt_node].second += val;
			return;
		}
		recUpdate(crt_node * 2 + 1, left, (left + right) / 2, range_l, range_r, val);
		recUpdate(crt_node * 2 + 2, (left + right) / 2 + 1, right, range_l, range_r, val);
		storage[crt_node].first =
			storage[crt_node * 2 + 1].first - storage[crt_node * 2 + 1].second
			+ storage[crt_node * 2 + 2].first - storage[crt_node * 2 + 2].second;
	}
	void recSingleUpdate(int crt_node, int left, int right, int pos, int val)
	{
		if (pos < left || pos >right)
			return;
		storage[crt_node].second += val;
		if (left == right)
		{
			return;
		}
		recSingleUpdate(crt_node * 2 + 1, left, (left + right) / 2,pos ,val);
		recSingleUpdate(crt_node * 2 + 2, (right + left) / 2 + 1, right,pos, val);
	}
	void recSegment(int crt_node, int left, int right)
	{
		if (left == right)
			return;
		recSegment(crt_node * 2 + 1, left, (left + right) / 2);
		recSegment(crt_node * 2 + 2, (right + left) / 2 + 1, right);
		storage[crt_node].first =
			storage[crt_node * 2 + 1].first
			+ storage[crt_node * 2 + 2].first;
	}
public:
	SumSegmentTree(int n, int l) : storage(4 * n), lower_bound(l), upper_bound(n + l - 1) {}

	void SegmentStructure()
	{
		recSegment(0, lower_bound, upper_bound);
	}
	void insert(int pos, int val)
	{
		recInsert(0, pos, lower_bound, upper_bound, val);
	}
	void updateRange(int range_low, int range_up, int val)
	{
		recUpdate(0, lower_bound, upper_bound, --range_low, --range_up, val);
	};
	int rangeQuery(int range_low, int range_up)
	{
		return recRange(0, lower_bound, upper_bound, --range_low, --range_up);
	};
	void update(int pos, int val)
	{
		recSingleUpdate(0, lower_bound, upper_bound, --pos, val);
	}
};

int main()
{
	ifstream in("datorii.in");
	ofstream out("datorii.out");
	int nrs, nr_op;
	in >> nrs >> nr_op;
	SumSegmentTree tree(nrs, 0);
	for (int i = 0; i < nrs; ++i)
	{
		int nr;
		in >> nr;
		tree.insert(i, nr);
	}
	tree.SegmentStructure();
	for (int i = 0; i < nr_op; ++i)
	{
		int op, param1, param2;
		in >> op >> param1 >> param2;
		if (op == 1)
		{
			out << tree.rangeQuery(param1, param2) << "\n";
		}
		else
		{
			tree.update(param1, param2);
		}
	}
	in.close();
	out.close();
	return 0;
}