Cod sursa(job #1293332)

Utilizator angelaAngela Visuian angela Data 15 decembrie 2014 19:32:49
Problema Hotel Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.62 kb
// OK 
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
 
class ST
{
public:
    ST( int _N )
    {
        N = _N;
        Max = maxR = maxL = flag = vector<int>( 4 * N );
        Build( 1, 1, N );
    }
 
    void Update( int x, int y, int v ) 
    {
        Update( 1, 1, N, x, y, v );
    }
 
    int Query() const
    {
        return Max[1];
    }
 
 protected:
    void Build( int nod, int st, int dr )
    {
        Max[nod] = maxL[nod] = maxR[nod] = dr - st + 1;
 
        if ( st != dr )
        {
            int m = ( st + dr ) / 2;
            Build( 2 * nod, st, m );
            Build( 2 * nod + 1, m + 1, dr );
        }
    }
 
    void Set( int nod, int val )
    {
        Max[nod] = maxR[nod] = maxL[nod] = val;
    }
 
    void PushDown( int nod, int st, int dr )
    {
        if ( Max[nod] == 0 )
        {
            Set( 2 * nod, 0 );
            Set( 2 * nod + 1, 0 );
        }
 
        if ( Max[nod] == dr - st + 1 )
        {
            int m = ( st + dr ) / 2;
            Set( 2 * nod, m - st + 1 );
            Set( 2 * nod + 1, dr - m );
        }
    }
 
    void Update( int nod, int st, int dr, int L, int R, int val )
    {
        if ( L <= st && dr <= R )
        {                                           
            Set( nod, ( dr - st + 1 ) * val ); // update just current node
            flag[nod] = true;
            return;                            // we're lazy: don't bother to update the sons
        }
         

		int m = ( st + dr ) / 2;

		if ( L <= m ) Update( 2 * nod, st, m, L, R, val );
		if ( m < R  ) Update( 2 * nod + 1, m + 1, dr, L, R, val );

		if ( flag[nod] || st == dr )
		{
			Set(nod, (dr - st + 1) * val);
			flag[nod] = false;
			return;
		}
		
		maxL[nod] = maxL[2 * nod];
		if ( maxL[2 * nod] == m - st + 1 )
			maxL[nod] += maxL[2 * nod + 1];

		maxR[nod] = maxR[2 * nod + 1];
		if ( maxR[2 * nod + 1] == dr - m )
			maxR[nod] += maxR[2 * nod];

		Max[nod] = max( Max[2 * nod], Max[2 * nod + 1] );
		Max[nod] = max( Max[nod], maxR[2 * nod] + maxL[2 * nod + 1] );
    }
    
private:
    vector <int> Max, maxR, maxL, flag;
    int N;
};
 
int n, m, op, i, L;
 
int main()
{
    ifstream fin("hotel.in");
    ofstream fout("hotel.out");
 
    fin >> n >> m;

    ST s(n);
	
    while ( m-- )
    {
        fin >> op;
      
        if ( op == 1 )
        {
            fin >> i >> L;
            s.Update( i, i + L - 1, 0 );
        }
 
        if ( op == 2 )
        {
            fin >> i >> L;
            s.Update( i, i + L - 1, 1 );
        }

        if ( op == 3 )
            fout << s.Query() << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}