Cod sursa(job #2223401)

Utilizator shantih1Alex S Hill shantih1 Data 20 iulie 2018 06:32:43
Problema Hotel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <iostream>
#include <fstream>

using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");

int n,m,p,c,i,j,a,b;
struct nod
{	int lst,ldr,lmx,spart;	} ar[400005];

void calc (int nd,int st,int dr)
{
	int md=(st+dr)/2;
	ar[nd].lmx=max(ar[2*nd].lmx,max(ar[2*nd+1].lmx,ar[2*nd].ldr+ar[2*nd+1].lst));
	ar[nd].lst=(ar[2*nd].lst==md-st+1)?(ar[2*nd].lst+ar[2*nd+1].lst):ar[2*nd].lst;
	ar[nd].ldr=(ar[2*nd+1].ldr==dr-md)?(ar[2*nd+1].ldr+ar[2*nd].ldr):ar[2*nd+1].ldr;
}	//asta calculeaza lungimea maxima pentru un nod din fii sai

void spart (int nd,int st,int dr)
{
	ar[nd].lmx=ar[nd].lst=ar[nd].ldr=0;
	ar[nd].spart=1;
	return;
}//asta imi seteaza un interval ca fiind spart.

void initial (int nd,int st,int dr)
{
	ar[nd].spart=0;
	if(st==dr)
	{
		ar[nd].lst=ar[nd].ldr=ar[nd].lmx=1;
		return;
	}
	int md=(st+dr)/2;
	initial(2*nd,st,md);
	initial(2*nd+1,md+1,dr);
	
	calc(nd,st,dr);
}//cu asta mi-am construit valorile initiale.

void block (int nd,int st,int dr)
{
	if(a<=st&&dr<=b)
	{
		spart(nd,st,dr);
		return;
	}
	int md=(st+dr)/2;
	if(max(a,st)<=min(b,md))	block(2*nd,st,md);
	if(max(a,md+1)<=min(b,dr))	block(2*nd+1,md+1,dr);
	
	calc(nd,st,dr);
}//cu asta fac intervalul dat "spart" si recalculez cu valoare nodurilor fiind 0.

void open (int nd,int st,int dr,bool ok)
{
	if(st==dr)
	{
		ar[nd].lst=ar[nd].ldr=ar[nd].lmx=1;
		ar[nd].spart=0;
		return;
	}
	if(ar[nd].spart==1)
	{
		ok=1;
		ar[nd].spart=0;
	}
	int md=(st+dr)/2;
	if(max(a,st)<=min(b,md))	open(2*nd,st,md,ok);
	else if(ok)	spart(2*nd,st,dr);
	if(max(a,md+1)<=min(b,dr))  open(2*nd+1,md+1,dr,ok);
	else if(ok)	spart(2*nd+1,md+1,dr);
	
	calc(nd,st,dr);
}

int main() {
	
	//bun deci care ii schema?
	//imi fac o fuctie care blocheaza cateva intervale dandu-le costul 0 apoi calculeaza raspunsul.
	//intervalele blocate le numesc sparte :)) 
	//a doua functie sparge intervalele si noteaza ca sparte toate subintervalele inafara de cel selectat.
	
	initial(1,1,12);
	
	fin>>n>>p;
	while(p--)
	{
		fin>>c;
		if(c==3)	fout<<ar[1].lmx<<"\n";
		if(c==1)
		{
			fin>>a>>b;
			b=a+b-1;
			block(1,1,n);
		}
		if(c==2)
		{
			fin>>a>>b;
			b=a+b-1;
			open(1,1,n,0);
		}
	}
}