Cod sursa(job #2753782)

Utilizator davidbejenariu2David Bejenariu davidbejenariu2 Data 24 mai 2021 13:53:29
Problema Plantatie Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.81 kb
#include <fstream>

using namespace std;

ifstream fin("plantatie.in");
ofstream fout("plantatie.out");

const int N = 501;

/// vom aplica algoritmul de rmq pentru o matrice N*N
int n;
int dp[10][N][N]; /// dp[k][i][j] = valoarea maxima dintr-un patrat de latura 2^k care are coltul stanga-sus de coordonate (i, j)
int lg[N]; /// lg[k] = [log2(k)]

void preCalc() {
    lg[2] = 1;

    for (int i = 3; i <= n; ++i) {
        lg[i] = lg[i / 2] + 1;
    }

    /**
     *   j
     * i . . . . .    . . . . .
     *   . 1 . 2 .    .       .
     *   . . . . . => .   5   .
     *   . 3 . 4 .    .       .
     *   . . . . .    . . . . .
     * Pentru a determina maximul pe un patrat de latura 2^k care are coltul stanga-sus in (i, j), ne putem folosi de ce am
     * memorat anterior pentru patratele de latura 2^(k - 1), impartind patratul mare in 4 mai mici si facand maxim pe acestea
     */

    for (int k = 1; (1 << k) <= n; ++k) {
        int pow = 1 << (k - 1);

        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                dp[k][i][j] = max(dp[k - 1][i][j], max(dp[k - 1][i][j + pow], max(dp[k - 1][i + pow][j], dp[k - 1][i + pow][j + pow])));
            }
        }
    }
}

/// pentru query aplicam aceeasi idee de a imparti patratul in alte 4 daca d nu este putere a lui 2
int query(int l, int c, int d) {
    int k = lg[d];
    int pow = 1 << k;

    return max(dp[k][l][c], max(dp[k][l][c + d - pow], max(dp[k][l + d - pow][c], dp[k][l + d - pow][c + d - pow])));
}

int main() {
    int m, l, c, d;

    fin >> n >> m;

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            fin >> dp[0][i][j];
        }
    }

    for (int i = 1; i <= m; ++i) {
        fin >> l >> c >> d;
        fout << query(l, c, d) << '\n';
    }

    fin.close();
    fout.close();

    return 0;
}