Cod sursa(job #773038)

Utilizator danalex97Dan H Alexandru danalex97 Data 31 iulie 2012 19:58:54
Problema Zeap Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <cstdio>
#include <fstream>
#include <vector>
#include <bitset>
#include <cstring>
using namespace std;

const int Size=5000000;
const int N=300000;

int A[N*4+11];
int A2[N*4+11];
int B[N*4+11];
int O[N*4+11];
int Act;

vector< pair<int,int> > V[Size+11];

ofstream G("zeap.out");

int poz(int a)
{ if ( a<0 ) 
	return (-a); 
else
	return a; }

void Ocupate(int Nod,int St,int Dr,int Pos,int Val) // Updateaza pozitiile ocupate
{
	if ( St==Dr )
	{
		O[Nod]=Val;
		return;
	}
	
	int Mid= (St+Dr) /2;
	if ( Pos<=Mid )
		Ocupate(2*Nod,St,Mid,Pos,Val);
	else
		Ocupate(2*Nod+1,Mid+1,Dr,Pos,Val);
	
	O[Nod]=min(O[2*Nod],O[2*Nod+1]);
}

int Query(int Nod,int St,int Dr) // Cauta cea mai de la stanga pozitie libera
{
	if ( St==Dr )
		return St;
	
	int Mid= (St+Dr) /2; 
	if ( !O[2*Nod] )
		return Query(2*Nod,St,Mid);
	return Query(2*Nod+1,Mid+1,Dr);
}

void Update(int Nod,int St,int Dr,int Pos,int Val)
{
	if ( St==Dr )
	{
		A[Nod]=Val;
		A2[Nod]=Val;
		return;
	}
	
	int Mid= (St+Dr) /2;
	if ( Pos<=Mid )
		Update(2*Nod,St,Mid,Pos,Val);
	else
		Update(2*Nod+1,Mid+1,Dr,Pos,Val);
	
	A[Nod]=max(A[2*Nod],A[2*Nod+1]);
	if (A2[2*Nod]==0) A2[2*Nod]=1<<30;
	if (A2[2*Nod+1]==0) A2[2*Nod+1]=1<<30;
	A2[Nod]=min(A2[2*Nod],A2[2*Nod+1]);
	
	B[Nod]=1<<30;
	if ( B[2*Nod] )  B[Nod]=min(B[Nod],B[2*Nod] );
	if ( B[2*Nod+1] )  B[Nod]=min(B[Nod],B[2*Nod+1] );
	if ( A[2*Nod] && A[2*Nod+1] ) B[Nod]=min(B[Nod],poz(A[2*Nod]-A[2*Nod+1]) );
	if ( A[2*Nod] && A2[2*Nod+1] ) B[Nod]=min(B[Nod],poz(A[2*Nod]-A2[2*Nod+1]) );
	if ( A2[2*Nod] && A[2*Nod+1] ) B[Nod]=min(B[Nod],poz(A2[2*Nod]-A[2*Nod+1]) );
	if ( A2[2*Nod] && A2[2*Nod+1] ) B[Nod]=min(B[Nod],poz(A2[2*Nod]-A2[2*Nod+1]) );
}

int Seek(int x) // marecheaza elementul folosit
{
	for (int it=0;it<int(V[x%Size].size());++it )
		if ( V[x%Size][it].first ==x )
			return 1;
	return 0;
}

void Push(int x,int pos)
{
	V[x%Size].push_back( make_pair(x,pos) );
}

int Pop(int x)
{
	for (int it=0;it<int(V[x%Size].size());++it )
		if ( V[x%Size][it].first ==x )
		{
			swap(V[x%Size][it],V[x%Size].back());
			int Ret=V[x%Size].back().second;
			V[x%Size].pop_back();
			return Ret;
		}
	return -1;
}

void Insert(int x)
{
	if ( Seek(x) ) 
	{
		G<<"-1\n";
		return;
	}
	
	++Act;
	int Pos=Query(1,1,N);
	Push( x,Pos );
	
	Ocupate( 1,1,N,Pos,1 );
	Update( 1,1,N,Pos,x );
}

void Erase(int x)
{
	if ( !Seek(x) ) 
	{
		G<<"-1\n";
		return;
	}
	
	--Act;
	int Pos=Pop( x );
	
	Ocupate( 1,1,N,Pos,0 );
	Update( 1,1,N,Pos,0 );
}

void Max()
{
	if ( Act>1 )
		G<<A[1]-A2[1]<<'\n';
	else
		G<<"-1\n";
}

void Min()
{
	if ( Act>1 )
		G<<B[1]<<'\n';
	else
		G<<"-1\n";
}

void Search(int x)
{
	G<<Seek(x)<<'\n';
}

int Get( char Str[],int act )
{
	int Rez=0;
	int S=strlen(Str);
	
	while ( Str[act]>='0' && Str[act]<='9' && act<S )
	{
		Rez=Rez*10+Str[act]-'0';
		++act;
	}
	return Rez;
}

int main()
{
	freopen("zeap.in","r",stdin);
	
	while ( 1 )
	{
		char Str[20]={0};
		gets(Str);
		
		if (Str[0]==0) 
		{
			G.close();
			return 0;
		}
		
		if (Str[1]==' ')
		{
			int x = Get( Str,2 );
			
			if ( Str[0] == 'I' ) Insert(x);
			if ( Str[0] == 'S' ) Erase(x);
			if ( Str[0] == 'C' ) Search(x);
		}
		
		if (Str[1]=='A') Max();
		if (Str[1]=='I') Min();
	}
}