Cod sursa(job #2901246)

Utilizator widzAndrei-Daniel Tava widz Data 13 mai 2022 14:18:18
Problema Datorii Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.1 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);
		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;
	}
	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) - storage[crt_node].second;
	}
	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;
		if (left == right)
		{
			storage[crt_node].second = 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);
		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;
	}

public:
	SumSegmentTree(int n,int l) : storage(4*n),lower_bound(l),upper_bound(n + l - 1){}
	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);
	};
};

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);
	}
	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.updateRange(param1,param1, param2);
		}
	}
	in.close();
	out.close();
	return 0;
}