Cod sursa(job #1170189)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 12 aprilie 2014 20:40:06
Problema Plantatie Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.05 kb
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

const int Nmax = 251;
const int LgMax = 9;

int RMQ[LgMax][LgMax][Nmax][Nmax];
int A[Nmax][Nmax];
int B[Nmax][Nmax];
int C[Nmax][Nmax];
int V[Nmax][Nmax];
int log2[Nmax];

int N, M, Q;
string s;

void gen_dp()
{
    for ( int i = 1; i <= N; ++i )
    {
        for ( int j = 1; j <= M; ++j )
        {
            if ( V[i][j] == 0 ) A[i][j] = A[i][j - 1] + 1;
            else                A[i][j] = 0;
        }
    }

    for ( int j = 1; j <= M; ++j )
    {
        for ( int i = 1; i <= N; ++i )
        {
            if ( V[i][j] == 0 ) B[i][j] = B[i - 1][j] + 1;
            else                B[i][j] = 0;
        }
    }

    for ( int i = 1; i <= N; ++i )
    {
        for ( int j = 1; j <= M; ++j )
        {
            C[i][j] = min( C[i - 1][j - 1] + 1, min( A[i][j], B[i][j] ) );
        }
    }

    for ( int i = 1; i <= N; ++i )
    {
        for ( int j = 1; j <= M; ++j )
        {
            cout << C[i][j] << " ";
        }

        cout<<endl;
    }
}

void gen_rmq()
{
    for ( int i = 2; i < Nmax; ++i )
            log2[i] = log2[i / 2] + 1;

    for ( int i = 1; i <= N; ++i )
            for ( int j = 1; j <= M; ++j )
                    RMQ[0][0][i][j] = C[i][j];

    int k = 0;

    for ( int l = 1; ( 1 << l ) <= M; ++l )
    {
        int p = 0;
        int q = ( 1 << ( l - 1 ) );

        for ( int i = 1; i + ( 1 << k ) - 1 <= N; ++i )
            for ( int j = 1; j + ( 1 << l ) - 1 <= M; ++j )
            {
                int m1 = max( RMQ[k][l - 1][i][j],     RMQ[k][l - 1][i][j + q] );
                int m2 = max( RMQ[k][l - 1][i + p][j], RMQ[k][l - 1][i + p][j + q] );

                RMQ[k][l][i][j] = max( m1, m2 );
            }
    }

    int l = 0;

    for ( int k = 1; ( 1 << k ) <= N; ++k )
    {
        int p = ( 1 << ( k - 1 ) );
        int q = 0;

        for ( int i = 1; i + ( 1 << k ) - 1 <= N; ++i )
            for ( int j = 1; j + ( 1 << l ) - 1 <= M; ++j )
            {
                int m1 = max( RMQ[k - 1][l][i][j],     RMQ[k - 1][l][i][j + q] );
                int m2 = max( RMQ[k - 1][l][i + p][j], RMQ[k - 1][l][i + p][j + q] );

                RMQ[k][l][i][j] = max( m1, m2 );
            }
    }

    for ( int k = 1; ( 1 << k ) <= N; ++k )
    {
        for ( int l = 1; ( 1 << l ) <= M; ++l )
        {
            int p = ( 1 << ( k - 1 ) );
            int q = ( 1 << ( l - 1 ) );

            for ( int i = 1; i + ( 1 << k ) - 1 <= N; ++i )
                for ( int j = 1; j + ( 1 << l ) - 1 <= M; ++j )
                {
                    int m1 = max( RMQ[k - 1][l - 1][i][j],     RMQ[k - 1][l - 1][i][j + q] );
                    int m2 = max( RMQ[k - 1][l - 1][i + p][j], RMQ[k - 1][l - 1][i + p][j + q] );

                    RMQ[k][l][i][j] = max( m1, m2 );
                }
        }
    }
}

int query( int x1, int y1, int x2, int y2 )
{
    if ( x1 > x2 ) return 0;
    if ( y1 > y2 ) return 0;

    int d1 = x2 - x1 + 1;
    int k1 = log2[d1];
    int p1 = 1 << k1;
    int sh1 = d1 - p1;

    int d2 = y2 - y1 + 1;
    int k2 = log2[d2];
    int p2 = 1 << k2;
    int sh2 = d2 - p2;

    int m1 = max( RMQ[k1][k2][x1][y1],       RMQ[k1][k2][x1 + sh1][y1] );
    int m2 = max( RMQ[k1][k2][x1][y1 + sh2], RMQ[k1][k2][x1 + sh1][y1 + sh2] );

    return max( m1, m2 );
}

int cauta( int x1, int y1, int x2, int y2 )
{
    int dim = min( x2 - x1, y2 - y1 );
    int st = 1, dr = dim, m, gasit = 0;

    while ( st <= dr )
    {
        m = ( st + dr ) / 2;

        if ( query( x1 + m, y1 + m , x2, y2 ) >= m )
        {
            gasit = m;
            st = m + 1;
        }
        else
        {
            dr = m - 1;
        }
    }

    return gasit;
}

int main()
{
    ifstream f("plantatie.in");
    ofstream g("plantatie.out");

    f >> N >> Q;

    M = N;

    for ( int i = 1; i <= N; ++i )
    {
        for ( int j = 1; j <= M; ++j )
                f >> C[i][j];
    }

    gen_rmq();

    while ( Q-- )
    {
        int x, y, k;

        f >> x >> y >> k;
        g << query( x, y, x + k - 1, y + k - 1 ) << "\n";
    }

    return 0;
}