Cod sursa(job #2786303)

Utilizator giotoPopescu Ioan gioto Data 20 octombrie 2021 17:53:38
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.71 kb
#include <bits/stdc++.h>
using namespace std;

class segTree{
	public : 
		segTree(int _n) : n(_n), arb(4 * n, 0), lazy(4 * n, 0) {};

		void build() {
			_build(1, n, 1);
		}

		int query(int x, int y) {
			return _query(x, y, 1, n, 1);
		}

		void init(vector <int> &a) {
			_init(1, n, 1, a);
		}

		void update(int pos, int val) {
			_update(pos, val, 1, n, 1);
		}

		void update(int x, int y, int val) {
			_update(x, y, val, 1, n, 1);
		}

	private :
		int n;
		vector <int> arb, lazy; // too lazy to do templates, be careful 
		
		static int comb(int x, int y) {
			return max(x, y);
		}

		void propag(int nod) {
			if (!lazy[nod]) return ;
			for (int i = nod << 1; i <= ((nod << 1) | 1); ++i) {
				arb[i] += lazy[nod];
				lazy[i] += lazy[nod];
			}
			lazy[nod] = 0;
		}

		void _build(int st, int dr, int nod) {
			arb[nod] = 0;
			if (st == dr) return ;

			int mij = (st + dr) / 2;
			_build(st, mij, nod << 1);
			_build(mij + 1, dr, (nod << 1) | 1);
		}

		void _init(int st, int dr, int nod, vector <int> &a) {
			if (st == dr) {
				arb[nod] = a[st];
				return ;
			}

			int mij = (st + dr) / 2;
			_init(st, mij, nod * 2, a);
			_init(mij + 1, dr, nod * 2 + 1, a);

			arb[nod] = comb(arb[nod * 2], arb[nod * 2 + 1]);
		}

		void _update(int pos, int val, int st, int dr, int nod) {
			if (st == dr) {
				arb[nod] = val; 
				return ;
			}

			propag(nod);
			int mij = (st + dr) / 2;

			if (pos <= mij) _update(pos, val, st, mij, nod << 1);
			else _update(pos, val, mij + 1, dr, (nod << 1) | 1);

			arb[nod] = comb(arb[nod << 1], arb[(nod << 1) | 1]);
		}

		void _update(int x, int y, int val, int st, int dr, int nod) {
			if (x <= st && dr <= y) {
				lazy[nod] += val;	
				arb[nod] += val;
				return ;
			}

			propag(nod);
			int mij = (st + dr) / 2;
			
			if (x <= mij) _update(x, y, val, st, mij, nod << 1);
			if (mij + 1 <= y) _update(x, y, val, mij + 1, dr, (nod << 1) | 1);

			arb[nod] = comb(arb[nod * 2], arb[nod * 2 + 1]);
		}

		int _query(int x, int y, int st, int dr, int nod) {
			if (x <= st && dr <= y) {
				return arb[nod];
			}

			propag(nod);
			int mij = (st + dr) / 2;

			if (x <= mij && mij + 1 <= y) return comb(_query(x, y, st, mij, nod * 2), _query(x, y, mij + 1, dr, nod * 2 + 1));
			if (x <= mij) return _query(x, y, st, mij, nod * 2);
			return _query(x, y, mij + 1, dr, nod * 2 + 1);
		}
};

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

	int n, q;
	scanf("%d%d", &n, &q);

	segTree aint(n);
	vector <int> a(n + 1, 0);
	for (int i = 1; i <= n ; ++i) 
		scanf("%d", &a[i]);

	aint.init(a);
	for (int i = 1; i <= q ; ++i) {
		int tip, x, y;
		scanf("%d%d%d", &tip, &x, &y);

		if (tip == 0) printf("%d\n", aint.query(x, y));
		else aint.update(x, y);
	}
	
	return 0;
}