Pagini recente » Cod sursa (job #1363357) | Cod sursa (job #1908129) | Cod sursa (job #1627249) | Cod sursa (job #2181806) | Cod sursa (job #790589)
Cod sursa(job #790589)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
using namespace std;
ifstream f("plantatie.in");
ofstream g("plantatie.out");
#define nmax 505
#define LogMax 10
#define ll long long
int n, m, a[nmax][nmax];
int Max[LogMax][nmax][nmax], Log[nmax];
void citeste(){
f >> n >> m;//dimensiunea matricei; numarul de query-uri
for(int i=1; i<=n; ++i){
for(int j=1; j<=n; ++j) f >> a[i][j];
}
}
void preprocesare(){
//initializez matricea;
for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) Max[0][i][j] = a[i][j];
for(int k=1; k<LogMax; ++k){
for(int i=1; i+(1<<k)-1<=n; ++i){
for(int j=1; j+(1<<k)-1<=n; ++j){
//acum am patru cazuri : defapt e asa ai un patrat mare pe care il poti imparti in patru patrate mai mici =>
//odata pot ramane la patratul i,j,k-1 al II-lea : i+(2^(k-1)),j,k-1
//al 3 lea : i, j+(2^(k-1)),k-1;
//al 4 lea : i+( 2^(k-1), j+( 2^(k-1) ), k-1;
Max[k][i][j] = Max[k-1][i][j];//pe primul patrat;
int new_i = i+( 1<<(k-1) );
Max[k][i][j] = max(Max[k][i][j], Max[k-1][new_i][j]);
int new_j = j+( 1<<(k-1) );
Max[k][i][j] = max(Max[k][i][j], Max[k-1][i][new_j]);
Max[k][i][j] = max(Max[k][i][j], Max[k-1][new_i][new_j]);
}
}
}
}
void rezolva(){
//pentru fiecare query de forma x, y, k trebuie sa precizes valoarea maxima din dreptunghiul cu coltul stanga sus in x,y de latura k
//asa ca fac un rmq in 2D;// mai exact imi preprocesez Max[k][i][j] = valoarea maxima din drepuntghiul cu coltul stanga sus in i, j, si
//coltul dreapta jos in [i+2^k-1, j+2^k-1]
preprocesare();
//imi fac Log[i] = pozitia celui mai semnificativ bit de 1 din reprez binara a lui i
for(int i=2; i<=n; ++i) Log[i] = Log[i/2] + 1;
for(int i=1; i<=m; ++i){
int x, y, latura;
f >> x >> y >> latura;
int x2 = x + latura-1;
int y2 = y + latura-1;//coltul dreapta jos al dreaptunghiul
//cout << x << " " << y << "\n";
//fac la fel ca si rmq 1D;
//latura defepat e lungimea intervalului
//caut cel mai mare k a. i. 2^k <= latura-1
int k = Log[latura];
//cout << k << "\n";
int rez = Max[k][x][y];
//aflu celelalte 3 intervale
int newX = x2 - (1<<k) + 1;
int newY = y2 - (1<<k) + 1;
rez = max(rez, Max[k][newX][y]);
rez = max(rez, Max[k][x][newY]);
rez = max(rez, Max[k][newX][newY]);
g << rez << "\n";
}
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}