Cod sursa(job #3279403)

Utilizator jumaracosminJumara Cosmin-Mihai jumaracosmin Data 22 februarie 2025 20:11:56
Problema Plantatie Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <bits/stdc++.h>

#pragma GCC optimize("O2")

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

/*
    RMQ 3D

    -> interogare de forma (i, j, lat) <=> Care este maximum din submatricea cu coltul stanga sus (i, j) si latura lat

    Implementation:a

    -> precalculare pentru fiecare (i, j) calculam maximele pe toate submatricele cu coltul stanga sus(i, j) si latura putere de 2

    -> trebuie sa folosim un tablou 3D de dimensiune n * n * log(n)
*/


const int size = 5e2 + 5;
const int log_size = 10;

int n, q;
int a[size][size];

struct SparseTable {

    int exponent[log_size];
    int spt[log_size][size][size]; // spt[e][i][j] = max in (i, j) cu latura 2^e

    void init(int n)
    {
        exponent[1] = 0;
        for(int i = 2; i <= n; ++i)
            exponent[i] = 1 + exponent[i / 2];

        // spt[0][i][j] = max in (i, j) cu latura 1, adica a[i][j]
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j)
                spt[0][i][j] = a[i][j];

        // spt[p][i][j] = max in (i, j) cu latura 2^p, putem sa ne folosim de spt[p - 1]

        // folosim lat ca sa ne asiguram ca ramanem in matrice => AM FOST APROAPE CORECT
        for(int p = 1, lat = 2; p <= exponent[n]; ++p, lat *= 2)
            for(int i = 1; i + lat - 1 <= n; ++i)
                for(int j = 1; j + lat - 1 <= n; ++j)
                {
                    int x = i + lat / 2;
                    int y = j + lat / 2;

                    spt[p][i][j] = std::max(
                                            std::max(spt[p - 1][i][j], spt[p - 1][x][y]),
                                            std::max(spt[p - 1][x][j], spt[p - 1][i][y])
                                        );
                }
    }

    int query(int xs, int ys, int L)
    {

        int lg2 = exponent[L];
        int len = (1 << lg2);

        int xm = xs + L - len;
        int ym = ys + L - len;

        // presupun ca se face cam la fel, insa acum facem pentru X-si, dar si pentru Y-ci
        // ne gandim la o compresie cu D&C in 4 submatrici

        return std::max(
                        std::max(spt[lg2][xs][ys], spt[lg2][xm][ys]),
                        std::max(spt[lg2][xs][ym], spt[lg2][xm][ym])
                    );
    }

} rmq;

int main()
{
    
    std::ios_base::sync_with_stdio(false);
    fin.tie(nullptr);
    fout.tie(nullptr);
    
    fin >> n >> q;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            fin >> a[i][j];

    rmq.init(n);
    
    while(q--)
    {
        int xs, ys, len;
        fin >> xs >> ys >> len;
        fout << rmq.query(xs, ys, len) << "\n";
    }

    return 0;
}