Cod sursa(job #861183)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 21 ianuarie 2013 09:29:00
Problema Plantatie Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.23 kb
#include <fstream>
#include <iostream>
#include <cstdlib>

#define nullptr NULL

using namespace std;

typedef unsigned char uint8;
    
template<uint8 N, char prev>
struct LookupTable;

template<char prev>
struct LookupTable<255, prev>
{
    LookupTable() :
        value(prev)
    {}
    char value;
};

template<uint8 N, char prev>
struct LookupTable
{
    LookupTable() :
        value(prev)
    {}

    char value;
    LookupTable<N+1, prev + (((N+1) & N) == 0)> next;
};

template<char prev>
struct LookupTable<0, prev>
{
    LookupTable() :
        value(prev)
    {}
    char value;
    LookupTable<1, 0> next;
};

class Log2Helper
{
public:

    static int Log2Of(int n)
    {
        if (ptr[n >> 24] > -1)
        {
            return ptr[n >> 24] + 24;
        }
        else if (ptr[n >> 16] > -1)
        {
            return ptr[n >> 16] + 16;
        }
        else if (ptr[n >> 8] > -1)
        {
            return ptr[n >> 8] + 8;
        }
        
        return ptr[n];
    }

    static LookupTable<0, -1> Log2LookupTable;
    static char* ptr;
};

LookupTable<0, -1> Log2Helper::Log2LookupTable;
char* Log2Helper::ptr = reinterpret_cast<char*>(&Log2LookupTable);

class CMatrixNxN
{
public:

    CMatrixNxN(int n) :
        m_iSize(n),
        m_pRawMatrix(new int[n*n])
    {}
    
    CMatrixNxN(const CMatrixNxN& other, int skipAhead)
    {
        m_iSize = other.size() - skipAhead;
        
        m_pRawMatrix = new int[m_iSize*m_iSize];
        
        for (int i=0; i<m_iSize; ++i)
        {
            for (int j=0; j<m_iSize; ++j)
            {
                (*this)[i][j] = std::max(std::max(other[i][j], other[i][j+skipAhead]),
                                         std::max(other[i+skipAhead][j], other[i+skipAhead][j+skipAhead]));
            }
        }
    }
    
    int* operator [] (int index)
    {
        return &m_pRawMatrix[index * m_iSize];
    }
    
    const int* operator [] (int index) const
    {
        return &m_pRawMatrix[index * m_iSize];
    }
    
    int size() const
    {
        return m_iSize;
    }
    
    ~CMatrixNxN()
    {
        if (m_pRawMatrix != nullptr)
        {
            delete m_pRawMatrix;
        }
    }
    
    void print() const
    {
        for (int i=0; i<m_iSize; ++i)
        {
            for (int j=0; j<m_iSize; ++j)
            {
                cout << (*this)[i][j] << " ";
            }
            cout << endl;
        }
    }
    
private:
    int m_iSize;
    int *m_pRawMatrix;
};

typedef CMatrixNxN* PCMatrixNxN;

int Query(const PCMatrixNxN* vppPlantation, int row, int col, int size)
{
    const int log2OfSize = Log2Helper::Log2Of(size);
    
    int max1 = std::max((*vppPlantation[log2OfSize])[row][col], (*vppPlantation[log2OfSize])[row][col + size - (1<<log2OfSize)]);
    int max2 = std::max((*vppPlantation[log2OfSize])[row + size - (1<<log2OfSize)][col], (*vppPlantation[log2OfSize])[row + size - (1<<log2OfSize)][col + size - (1<<log2OfSize)]);
    
    return std::max(max1, max2);
}

int main()
{
    int n, m;
    fstream fin("plantatie.in", fstream::in);
    fstream fout("plantatie.out", fstream::out);
    
    fin >> n >> m;
    //cout << n << " " << m << endl;
    
    PCMatrixNxN* vppPlantation = new PCMatrixNxN[Log2Helper::Log2Of(n) + 1];

    vppPlantation[0] = new CMatrixNxN(n);
    
    for (int i=0; i<n; ++i)
    {
        for (int j=0; j<n; ++j)
        {
            fin >> (*vppPlantation[0])[i][j];
            
            //cout << (*vppPlantation[0])[i][j] << " ";
        }
        //cout << endl;
    }
    //cout << endl;

    for (int i=1; (1<<i)<=n; ++i)
    {
        vppPlantation[i] = new CMatrixNxN(*vppPlantation[i-1], 1<<(i-1));
        //vppPlantation[i]->print();
        //cout << endl;
    }
    
    for (int i=0; i<m; ++i)
    {
        int row, col, size;
        fin >> row >> col >> size;
        
        //cout << row-1 << " " << col-1 << " " << size << endl;
        fout << Query(vppPlantation, row-1, col-1, size) << "\n";
    }
    
    /*for (int i=0; i<256; ++i)
    {
        cout << i << "  " << Log2Helper::Log2Of(i) << endl;
    }*/
    return 0;
}