Cod sursa(job #2630065)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 23 iunie 2020 22:36:55
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <fstream>
#include <algorithm>

using namespace std;

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

const int NMAX = 300;
const int QMAX = 20000;

int N, Q;
int mat[NMAX + 2][NMAX + 2];

struct field
{
    int val, ind;

    bool operator < (const field other) const
    {
        return val > other.val;
    }
};

field v[NMAX * NMAX + 2];

int dad[NMAX * NMAX + 2];

struct qr
{
    int x1, y1, x2, y2;
    int ind, ans;

    bool operator < (const qr other) const
    {
        return ans > other.ans;
    }
};

qr q[QMAX + 2];

inline bool cmp (const qr A, const qr B)
{
    return A.ind < B.ind;
}

int Root(int d)
{
    if(d == dad[d])
        return d;

    return dad[d] = Root(dad[d]);
}

void dojoin(int p, int q)
{
    p = Root(p);
    q = Root(q);

    if(p != q)
        dad[q] = p;
}

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
void join(field f)
{
    int p = f.ind;

    int x = p / N + 1, y = p % N + 1;

    for(int i = 0; i < 4; i++)
    {
        int xx = x + dx[i];
        int yy = y + dy[i];

        if(1 <= xx && xx <= N && 1 <= yy && yy <= N)
            if(mat[xx][yy] >= mat[x][y])
                dojoin(p, (xx - 1) * N + yy - 1);
    }
}

bool joined(qr c)
{
    int p1 = (c.x1 - 1) * N + c.y1 - 1;
    int p2 = (c.x2 - 1) * N + c.y2 - 1;

    if(Root(p1) == Root(p2))
        return true;

    return false;
}

void reset()
{
    for(int i = 0; i <= N * N; i++)
        dad[i] = i;
}

int main()
{
    cin >> N >> Q;

    int k = 0;
    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= N; j++)
        {
            cin >> mat[i][j];

            ++k;
            v[k] = {mat[i][j], k - 1};
            dad[k] = k;
        }

    sort(v + 1, v + k + 1);

    for(int i = 1; i <= Q; i++)
    {
        cin >> q[i].x1 >> q[i].y1 >> q[i].x2 >> q[i].y2;
        q[i].ind = i;
    }

    for(int step = 20; step >= 0; step--)
    {
        reset();

        sort(q + 1, q + Q + 1);

        int pos = 1;
        for(int i = 1; i <= Q; i++)
        {
            while(pos <= k && v[pos].val >= (1 << step) + q[i].ans)
                join(v[pos]), pos++;

            if(joined(q[i]))
                q[i].ans += (1 << step);
        }
    }

    sort(q + 1, q + Q + 1, cmp);

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

    return 0;
}