Cod sursa(job #3120786)

Utilizator LucaMuresanMuresan Luca Valentin LucaMuresan Data 8 aprilie 2023 15:48:42
Problema Matrice 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in ("matrice2.in");
ofstream out ("matrice2.out");

const int NMAX = 300;
const int QMAX = 2e4;
const int dx[] = {-1, +1, 0, 0};
const int dy[] = {0, 0, -1, +1};

int n;
int a[NMAX + 5][NMAX + 5];
bitset<NMAX + 5>ok[NMAX + 5];

bool comp (pair<int, int>x, pair<int, int>y)
{
    return a[x.first][x.second] > a[y.first][y.second];
}

struct query
{
    int x1, y1, x2, y2;
    int res, idx;

    bool operator < (const query aux) const
    {
        return res > aux.res;
    }
};

query Q[QMAX + 5];
int p[NMAX * NMAX + 5];
int sz[NMAX * NMAX + 5];

int root (int u)
{
    if (u == p[u]) return u;
    return p[u] = root(p[u]);
}

void unite (int x, int y)
{
    x = root(x), y = root(y);
    if (x == y) return;
    if (sz[x] > sz[y]) swap(x, y);
    p[x] = y;
    sz[y] += sz[x];
}

inline int getVal (int x, int y)
{
    return n * (x - 1) + y;
}

void init()
{
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=n; j++)
        {
            int x = getVal(i, j);
            p[x] = x;
            sz[x] = 1;
            ok[i][j] = false;
        }
    }
}

int main()
{
    int q;
    in >> n >> q;

    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=n; j++)
        {
            in >> a[i][j];
        }
    }

    vector<pair<int, int>>v;
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=n; j++)
            v.push_back({i, j});
    }

    sort(v.begin(), v.end(), comp);

    for (int i=1; i<=q; i++)
        in >> Q[i].x1 >> Q[i].y1 >> Q[i].x2 >> Q[i].y2, Q[i].res = 1, Q[i].idx = i;

    for (int jump=(1<<19); jump>0; jump>>=1)
    {
        sort(Q+1, Q+q+1);

        init();

        int pos = 0;

        for (int i=1; i<=q; i++)
        {
            while (pos < (int)v.size() && Q[i].res + jump <= a[v[pos].first][v[pos].second])
                {
                    ok[v[pos].first][v[pos].second] = true;
                    for (int k=0; k<4; k++)
                    {
                        int x = v[pos].first + dx[k];
                        int y = v[pos].second + dy[k];
                        if (x > 0 && y > 0 && x <= n && y <= n && ok[x][y])
                            unite(getVal(x, y), getVal(v[pos].first, v[pos].second));
                    }
                    pos++;
                }

            if (root(getVal(Q[i].x1, Q[i].y1)) == root(getVal(Q[i].x2, Q[i].y2)))
                Q[i].res += jump;
        }
    }

    for (int i=1; i<=q; i++)
        out << Q[i].res << '\n';

    return 0;
}