Cod sursa(job #2970673)

Utilizator Dragono63Stanciu Rares Stefan Dragono63 Data 25 ianuarie 2023 18:20:43
Problema Matrice 2 Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.94 kb
#include <bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
using ll = long long;

using namespace std;

const int NMAX = 305;
const int QMAX = 2e4 + 5;
/*******************************/
// INPUT / OUTPUT

ifstream f("matrice2.in");
ofstream g("matrice2.out");
/*******************************/
/// GLOBAL DECLARATIONS

int N, Q;
int query_ans[QMAX];
int grid[NMAX][NMAX], h[NMAX][NMAX];
pii par[NMAX][NMAX];

struct Query
{
    int x1, y1, x2, y2, val, idx;

    const bool operator < (const Query &other) const {
        if (val == other.val)
        {
            return idx < other.idx;
        }
        return val > other.val;
    }
};

struct Tile
{
    int x, y, val;
};

vector <Query> queries, new_queries;
vector <Tile> tiles;
vector <int> dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
/*******************************/
/// FUNCTIONS

void ReadInput();
void Solution();
void Output();
/*******************************/
///-------------------------------------
inline void ReadInput()
{
    f >> N >> Q;
    
    for (int i = 1 ; i <= N ; ++ i)
    {
        for (int j = 1 ; j <= N ; ++ j)
        {
            f >> grid[i][j];
            tiles.push_back({i, j, grid[i][j]});
        }
    }

    int x1, y1, x2, y2;
    for (int i = 0 ; i < Q ; ++ i)
    {
        f >> x1 >> y1 >> x2 >> y2;
        queries.push_back({x1, y1, x2, y2, 0, i});
    }
}
///-------------------------------------
bool comp_tiles(const Tile &a, const Tile &b)
{
    return a.val > b.val;
}
///-------------------------------------
inline void init_paduri()
{
    for (int i = 1 ; i <= N ; ++ i)
    {
        for (int j = 1 ; j <= N ; ++ j)
        {
            par[i][j] = {i, j};
            h[i][j] = 1;
        }
    }
}
///-------------------------------------
pii find(int x, int y)
{
    if (par[x][y].first == x && par[x][y].second == y) return par[x][y];
    par[x][y] = find(par[x][y].first, par[x][y].second);
    return par[x][y];
}
///-------------------------------------
void uneste(pii a, pii b)
{
    pii aa = find(a.first, a.second), bb = find(b.first, b.second);

    if (h[aa.first][aa.second] < h[bb.first][bb.second])
        swap(aa, bb);
    
    h[aa.first][aa.second] += h[bb.first][bb.second];
    par[bb.first][bb.second] = aa;
}
///-------------------------------------
void solve_queries(int step)
{
    init_paduri();
    // for (auto q: queries)
    //     g << q.x1 << " " << q.y1 << " " << q.x2 << " " << q.y2 << " " << q.val << "\n";
    // g << "//-----------------------------\n";
    int qIdx = 0, xx, yy;
    Tile t;
    new_queries.clear();
    for (int k = 0 ; k < tiles.size() ; ++ k)
    {
        t = tiles[k];
        for (int i = 0 ; i < 4 ; ++ i)
        {
            xx = t.x + dx[i];
            yy = t.y + dy[i];

            if (grid[xx][yy] >= t.val && find(t.x, t.y) != find(xx, yy))
                uneste({t.x, t.y}, {xx, yy});
        }

        if (k != tiles.size() - 1 && t.val == tiles[k + 1].val) continue;
        while (qIdx < Q && queries[qIdx].val + step >= t.val)
        {
            if (find(queries[qIdx].x1, queries[qIdx].y1) == find(queries[qIdx].x2, queries[qIdx].y2))
            {
                query_ans[queries[qIdx].idx] += step;
            }
            ++ qIdx;
        }
    }

    for (auto q: queries)
        new_queries.push_back({q.x1, q.y1, q.x2, q.y2, query_ans[q.idx], q.idx});
    sort(new_queries.begin(), new_queries.end());
    queries = new_queries;
}
///-------------------------------------
inline void Solution()
{
    sort(tiles.begin(), tiles.end(), comp_tiles);
    sort(queries.begin(), queries.end());

    int p = (1 << 20), s = 0;
    while (p)
    {
        solve_queries(p);
        p >>= 1;
    }
}
///-------------------------------------
inline void Output()
{
    for (int i = 0 ; i < Q ; ++ i) 
        g << query_ans[i] << "\n";
}
///-------------------------------------
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    ReadInput();
    Solution();
    Output();
    return 0;
}