Cod sursa(job #2970684)

Utilizator Dragono63Stanciu Rares Stefan Dragono63 Data 25 ianuarie 2023 18:33:33
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.83 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 adauga(int x, int y)
{
    int xx, yy;
    for (int i = 0 ; i < 4 ; ++ i)
    {
        xx = x + dx[i];
        yy = y + dy[i];

        if (grid[xx][yy] >= grid[x][y] && find(x, y) != find(xx, yy))
            uneste({x, y}, {xx, yy});
    }
}
///-------------------------------------
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";
    new_queries.clear();
    int j = 0;
    Query q;
    for (int i = 0 ; i < Q ; ++ i)
    {
        q = queries[i];
        while (q.val + step <= tiles[j].val)
        {
            adauga(tiles[j].x, tiles[j].y);
            ++ j;
        }

        if (find(q.x1, q.y1) == find(q.x2, q.y2))
            query_ans[q.idx] += step;
    }

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