Pagini recente » Cod sursa (job #225101) | Cod sursa (job #2190877) | Cod sursa (job #2189088) | Cod sursa (job #1727088) | Cod sursa (job #2686359)
#include <bits/stdc++.h>
using namespace std;
ifstream f("plantatie.in");
ofstream g("plantatie.out");
int n,m,i,j,x,k,pas,p,maxim,A[510][510][15];
int main()
{
// RMQ pe matrice
// A[i][j][k] = maximul valorilor determinate de patratul ce are coltul stanga-sus in (i;j) si lungimea laturii = 2^k
// Adica patratul (i;j) pana in (i + 2^k -1; j + 2^k -1);
f>>n>>m;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
f>>x;
A[i][j][0]=x;
}
}
// Construim A
// A[i][j][k] = maximul dintre patratul [ (i;j) -> (i + 2^(k-1) - 1; j + 2^(k-1) - 1) ]
// [ ( i;j + 2^(k-1) ) -> (i + 2^(k-1) - 1; j + 2^(k-1) + 2^(k-1) - 1)] = [ ( i;j + 2^(k-1) ) -> (i + 2^(k-1) - 1; j + 2^k - 1)]
// [ ( i + 2^(k-1);j ) -> (i + 2^(k-1) + 2^(k-1) - 1; j + 2^(k-1) - 1)] = [ ( i + 2^(k-1);j ) -> (i + 2^k - 1; j + 2^(k-1) - 1)]
// [ ( i + 2^(k-1);j + 2^(k-1) ) -> (i + 2^k - 1; j + 2^k - 1) ]
// TOATE ACESTE PATRATE SE POT INTERSECTA, DAR REUNIUNEA LOR DA PATRATUL DORIT
for(k=1;(1<<k)<=n;k++)
{
for(i=1;i+(1<<k)-1<=n;i++)
{
for(j=1;j+(1<<k)-1<=n;j++)
{
maxim=max(A[i][j][k-1], A[i][j+(1<<(k-1))][k-1]);
maxim=max(maxim, A[i+(1<<(k-1))][j][k-1]);
maxim=max(maxim, A[i+(1<<(k-1))][j+(1<<(k-1))][k-1]);
A[i][j][k]=maxim;
}
}
}
// REZOLVAM
for(pas=1;pas<=m;pas++)
{
f>>i>>j>>k;
// cautam un p, astfel incat 2^p <= lungime = k
// iar solutia o sa fie reuniunea patratelor [ (i;j) -> (i + 2^p - 1; j + 2^p - 1) ] --- stanga sus
// [ (i;j + k - 2^p) -> (i + 2^p - 1; j + k - 2^p + 2^p - 1) ] = [ (i;j - 2^p + 1) -> (i + 2^p -1; j + k -1) ] --- dreapta sus
// [ (i + k - 2^p;j) -> (i + k - 1; j + 2^p - 1) ] --- stanga jos
// [ (i + k - 2^p;j + k - 2^p) -> (i+k-1; j+k-1)] --- dreapta jos
p=log2(k);
maxim=max(A[i][j][p], A[i][j+k-(1<<p)][p]);
maxim=max(maxim, A[i+k-(1<<p)][j][p]);
maxim=max(maxim, A[i+k-(1<<p)][j+k-(1<<p)][p]);
g<<maxim<<'\n';
}
return 0;
}