Cod sursa(job #2347406)

Utilizator BogdanAlexandruBogdan-Alexandru Dig BogdanAlexandru Data 18 februarie 2019 19:26:59
Problema Plantatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.47 kb
#include <stdio.h>
#define Max(a,b) ( a>b ? a : b)
using namespace std;
FILE *f,*g;
int RMQ[20][510][510];
int log[510],N,M;
void CreateLog()///retin logaritmul fiecarui nivel pentru a-l accesa ulterior in O(1)
{
    int i;
    for(i=2;i<=N;i++)log[i]=1+log[i/2];
}
void Read()
{
    int i,j;
    fscanf(f,"%d %d",&N,&M);
    for(i=1;i<=N;i++)
        for(j=1;j<=N;j++)fscanf(f,"%d",&RMQ[0][i][j]);
    CreateLog();
}
void CreateRMQ()
{
    int i,j,k,pow;
    for(k=1;k<=log[N];++k)///formez RMQ in functie de latura fiecarei parcele: Nivelul unu va contine patratele cu latura de doi, nivelul doi cu latura de patru... nivelul n cu latura de 2^n
    {
        pow=1<<(k-1);
        for(i=1;i+(1<<k)<=N+1;++i)
            for(j=1;j+(1<<k)<=N+1;++j)
                RMQ[k][i][j]=Max(Max(RMQ[k-1][i][j],RMQ[k-1][i+pow][j]),Max(RMQ[k-1][i+pow][j+pow],RMQ[k-1][i][j+pow]));
    }
}
void Solve()
{
    int M1,M2,X,Y,L,Level,Q;
    while(M)///separ fiecare portiunea in 4 si calculez maximul dintre ele
    {
        --M;
        fscanf(f,"%d%d%d",&X,&Y,&L);
        Level=log[L];///aflu nivelul in functie de latura acestuia
        Q=(1<<Level);
        M1=Max(RMQ[Level][X][Y],RMQ[Level][X][Y+L-Q]);
        M2=Max(RMQ[Level][X+L-Q][Y],RMQ[Level][X+L-Q][Y+L-Q]);
        fprintf(g,"%d\n",Max(M1,M2));
    }
}
int main()
{
    f=fopen("plantatie.in","r");g=fopen("plantatie.out","w");
    Read();CreateRMQ();Solve();
    fclose(f);fclose(g);
    return 0;
}