Cod sursa(job #3279404)

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

#pragma GCC optimize("O2")

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

//#define fin std::cin 
//#define fout std::cout

/*
    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()
    {
        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]
        // latura se dubleaza si sus si jos, so probabil ca vom avea 4 componente ?? <- correct assumption and formula
        // spt[p - 1][i][j], spt[p - 1][i + 2^(p - 1)][j], spt[p - 1][i][J + 2^(p - 1)], spt[p - 1][i + 2^(p - 1)][j + 2^(p - 1)]

        for(int p = 1; p <= exponent[n]; ++p)
            for(int i = 1; i <= n; ++i)
                for(int j = 1; j <= n; ++j)
                {
                    int x = i + (1 << (p - 1));
                    int y = j + (1 << (p - 1));

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

    int query(int xs, int ys, int len)
    {
        int xf = xs + len - 1;
        int yf = ys + len - 1;

        int lg2 = exponent[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
        
        int ans1 = std::max(spt[lg2][xs][ys], spt[lg2][xf - (1 << lg2) + 1][ys]);
        int ans2 = std::max(spt[lg2][xs][yf - (1 << lg2) + 1], spt[lg2][xf - (1 << lg2) + 1][yf - (1 << lg2) + 1]);

        return std::max(ans1, ans2);
    }

} 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();

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

    return 0;
}