Cod sursa(job #1049202)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 7 decembrie 2013 01:01:54
Problema Hotel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.5 kb
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iterator>
#include <assert.h>
using namespace std;


const string file = "hotel";

const string infile = file + ".in";
const string outfile = file + ".out";

const int INF = 0x3f3f3f3f;



struct NodeInfo
{
	NodeInfo(int ans = 1, int left = 1, int right = 1, int length = 1, bool lazy = true)
	{
		this->ans = ans;
		this->left = left;
		this->right = right;
		this->length = length;
		this->lazy = lazy;
	}
	int ans;
	int left;
	int right;
	int length;
	bool lazy;
};


class SegmentTree
{
public:
	SegmentTree(int st, int dr);

	int query(int a, int b);
	void update(int a, int b, int free);


private:
	void updateNode(NodeInfo& info, NodeInfo& l, NodeInfo& r);
	void query(int nod, int st, int dr, int a, int b, NodeInfo& info);
	void update(int nod, int st, int dr, int a, int b, int value);

	void forceUpdate(int nod, int st, int dr, int a, int b, int value);

	int _st;
	int _dr;
	vector<NodeInfo> _data;

};

void SegmentTree::updateNode(NodeInfo& info, NodeInfo& l, NodeInfo& r)
{
	info.ans = max(l.ans, r.ans);
	info.ans = max(info.ans, l.right + r.left);
	info.left = l.left;
	info.right = r.right;
	info.length = l.length + r.length;

	if(l.left == l.length)
	{
		info.left = l.left + r.left;
	}
	if(r.right == r.length)
	{
		info.right = l.right + r.right;
	}

	
}

SegmentTree::SegmentTree(int st, int dr)
{
	_st = st;
	_dr = dr;
	int size = dr - st + 1;

	int c = 1;
	while( c < size)
		c <<= 1;
	c <<= 1;
	c++;
	_data.resize(c);
}


void SegmentTree::query(int nod, int st, int dr, int a, int b, NodeInfo& info)
{
	if(_data[nod].lazy == true)
	{
		forceUpdate(nod, st, dr, st ,dr, _data[nod].ans);
	}

	if(a <= st && dr <= b)
	{
		info = _data[nod];
		return;
	}

	int mid = (dr + st)/2;

	NodeInfo l;
	NodeInfo r;

	if(a <= mid && mid < b)
	{
		query(nod*2, st, mid, a, b, l);
		query(nod*2 + 1, mid + 1, dr, a, b, r);
		updateNode(info, l, r);
	}
	else if(a <= mid)
	{
		query(nod*2, st, mid, a, b, l);
		info = l;
	}
	else if( mid < b)
	{
		query(nod*2 + 1, mid + 1, dr, a, b, r);
		info = r;
	}
}

void SegmentTree::update(int nod, int st, int dr, int a, int b, int value)
{
	

	if(a <= st && dr <= b)
	{
		if(value == 1)
		{
			_data[nod] = NodeInfo(dr - st + 1, dr - st + 1, dr - st + 1, dr - st + 1);
		}
		else
		{
			_data[nod] = NodeInfo(0, 0, 0, dr - st + 1);
		}

		if(st == dr)
		{
			_data[nod].lazy = false;
		}

		return;	
	}

	if(_data[nod].lazy == true)
	{
		forceUpdate(nod, st, dr, st, dr, _data[nod].ans);
	}

	int mid = (dr + st)/2;


	if(a <= mid)
	{
		update(nod*2, st, mid, a, b, value);
	}

	if( mid < b)
	{
		update(nod*2 + 1, mid + 1, dr, a, b, value);
	}
	updateNode(_data[nod], _data[nod*2], _data[nod*2+1]);
}


void SegmentTree::forceUpdate(int nod, int st, int dr, int a, int b, int value)
{
	if(value == 1)
	{
		_data[nod] = NodeInfo(dr - st + 1, dr - st + 1, dr - st + 1, dr - st + 1);
	}
	else
	{
		_data[nod] = NodeInfo(0, 0, 0, dr - st + 1);
	}

	_data[nod].lazy = false;

	if(st == dr)
		return;

	int mid = (dr + st)/2;

	forceUpdate(nod*2, st, mid, a, b, value);
	forceUpdate(nod*2 + 1, mid + 1, dr, a, b, value);
}


void SegmentTree::update(int a, int b, int free)
{
	update(1, _st, _dr, a, b, free);
}

int SegmentTree::query(int a, int b)
{
	NodeInfo info;
	query(1, _st, _dr, a, b, info);
	return info.ans;
}


int main()
{
#ifdef ONLINE_JUDGE
	ostream &fout = cout;
	istream &fin = cin;
#else
	fstream fout(outfile.c_str(), ios::out);
	fstream fin(infile.c_str(), ios::in);
#endif	

	int N, P;
	fin >> N >> P;
	SegmentTree tree(1, N);

	for(int i = 0; i < P; i++)
	{
		int op;
		int x, y;
		fin >> op;
		if(op == 1)
		{
			fin >> x >> y;
			tree.update(x, x + y - 1, 0);
		}
		else if(op == 2)
		{
			fin >> x >> y;
			tree.update(x, x + y - 1, 1);
		}
		else if(op == 3)
		{
			fout << tree.query(1, N) << "\n";
		}
	}


#ifdef ONLINE_JUDGE
#else

	fin.close();
	fout.close();
#endif
}