Cod sursa(job #2963601)

Utilizator acostin643costin andrei acostin643 Data 11 ianuarie 2023 16:23:13
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <fstream>
#include <algorithm>

using namespace std;

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

int di[4] = {0, 1, 0, -1};
int dj[4] = {1, 0, -1, 0};

int N, Q, cnt;
int h[90005];
int t[90005];
int a[305][305];

int boss(int x)
{
    while(x != t[x])
        x = t[x];
    return x;
}

void unite(int x, int y)
{
    x = boss(x);
    y = boss(y);
    if(x == y)
        return;
    if(h[x] >= h[y])
        h[x]++, t[y] = x;
    else
        h[y]++, t[x] = y;
}

bool isOk(int i, int j)
{
    if(i < 1 || j < 1 || i > N || j > N)
        return false;
    return true;
}

bool solve(int x, int y, int z, int t)
{
    int nod1 = (x - 1) * N + y;
    int nod2 = (z - 1) * N + t;
    return boss(nod1) == boss(nod2);
}

struct elem
{
    int val, lin, col, ind;
    bool operator < (const elem &other) const
    {
        return val > other.val;
    }
};
elem v[90005];

struct queries
{
    int x, y, z, t, ans, ind;
    bool operator < (const queries &other) const
    {
        return ans > other.ans;
    }
};
queries ask[20005];

bool cmp(queries a, queries b)
{
    return a.ind < b.ind;
}

void mark(elem x)
{
    int lin = x.lin;
    int col = x.col;
    for(int i = 0; i < 4; i++)
    {
        int lin_nou = lin + di[i];
        int col_nou = col + dj[i];
        if(isOk(lin_nou, col_nou) && a[lin_nou][col_nou] >= a[lin][col])
        {
            int nod1 = (lin - 1) * N + col;
            int nod2 = (lin_nou - 1) * N + col_nou;
            unite(nod1, nod2);
        }
    }
}

void rst()
{
    for(int i = 1; i <= N * N; i++)
        h[i] = 1, t[i] = i;
}

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

    for(int i = 1; i <= N; i++)
    {
        for(int j = 1; j <= N; j++)
        {
            fin >> a[i][j];
            cnt++;
            v[cnt] = {a[i][j], i, j, cnt};
        }
    }

    for(int i = 1; i <= Q; i++)
    {
        fin >> ask[i].x >> ask[i].y >> ask[i].z >> ask[i].t;
        ask[i].ans = 0;
        ask[i].ind = i;
    }
    sort(v + 1, v + cnt + 1);
    for(int i = 20; i >= 0; i--)
    {
        int bit = (1 << i);
        sort(ask + 1, ask + Q + 1);
        int poz = 1;
        for(int j = 1; j <= N * N; j++)
            h[j] = 1, t[j] = j;
        for(int j = 1; j <= Q; j++)
        {
            while(poz <= cnt && v[poz].val >= bit + ask[j].ans)
            {
                mark(v[poz]);
                poz++;
            }
            if(solve(ask[j].x, ask[j].y, ask[j].z, ask[j].t))
            {
                ask[j].ans += bit;
            }
        }
    }
    sort(ask + 1, ask + Q + 1, cmp);
    for(int i = 1; i <= Q; i++)
    {
        fout << ask[i].ans << '\n';
    }

    fin.close();
    fout.close();
    return 0;
}