Cod sursa(job #3185685)

Utilizator AswVwsACamburu Luca AswVwsA Data 19 decembrie 2023 21:08:59
Problema Matrice 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <fstream>
#include <algorithm>
#include <vector>
#define ll long long
using namespace std;

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

int v[NMAX + 1][NMAX + 1];
vector <pair <int, int> > poz[NMAX * NMAX + 1];

struct ob
{
    int i1, j1, i2, j2;
    int ans;
};

ob query[QMAX + 1];
int n;

vector <int> norm;
int cnt;
int normalize()
{
    int i, j;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
            norm.push_back(v[i][j]);
    sort(norm.begin(), norm.end());
    norm.resize(unique(norm.begin(), norm.end()) - norm.begin());


    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
        {
            v[i][j] = lower_bound(norm.begin(), norm.end(), v[i][j]) - norm.begin();
            poz[v[i][j]].push_back({i, j});
        }
    return norm.size();
}

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

pair <int, int> tata[NMAX + 1][NMAX + 1];

pair <int, int> dad(int a, int b)
{
    if (tata[a][b] == make_pair(a, b))
        return {a, b};
    tata[a][b] = dad(tata[a][b].first, tata[a][b].second);
    return tata[a][b];
}

void joint(int a, int b, int c, int d)
{
    pair <int, int> x = dad(a, b);
    pair <int, int> y = dad(c, d);
    tata[x.first][x.second] = y;
}

void combine(int a, int b, int val)
{
    for (int k = 0; k < 4; k++)
    {
        int ni = a + di[k];
        int nj = b + dj[k];
        if (ni >= 1 and ni <= n and nj >= 1 and nj <= n and
                v[ni][nj] >= val)
            joint(a, b, ni, nj);
    }
}

void bs(int st, int dr, vector <int> &ceva, bool ok)
{
    if (st > dr)
        return ;
    int i, med = ((st + dr) >> 1);
    vector <int> good, bad;

    if (st == dr)
    {
        if (ok == false)
            for (pair <int, int> x : poz[st])
                combine(x.first, x.second, st);
        else
            for (pair <int, int> x : poz[st])
                tata[x.first][x.second] = x;
    }
    else
    {

        if (ok == false)
        {
            for (i = med + 1; i <= dr; i++)
                for (pair <int, int> x : poz[i])
                    combine(x.first, x.second, med + 1);
        }
        else
        {
             for (i = st; i <= med; i++)
                for (pair <int, int> x : poz[i])
                    tata[x.first][x.second] = x;
        }
    }
    for (int x : ceva)
        if (dad(query[x].i1, query[x].j1) == dad(query[x].i2, query[x].j2))
        {
            query[x].ans = norm[med];
            good.push_back(x);
        }
        else
            bad.push_back(x);

    if (st != dr)
    {
        bs(st, med, bad, 0);
        bs(med + 1, dr, good, 1);
    }
}
/*
5 1
9 5 9 8 7
2 1 1 3 8
1 3 9 4 6
4 1 8 6 7
2 4 5 5 6
5 5 1 5
*/

signed main()
{
    ifstream cin("matrice2.in");
    ofstream cout("matrice2.out");
    int i, j, q;
    cin >> n >> q;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
        {
            cin >> v[i][j];
            tata[i][j] = {i, j};
        }
    cnt = normalize();

    vector <int> qs;
    for (i = 1; i <= q; i++)
    {
        cin >> query[i].i1 >> query[i].j1 >> query[i].i2 >> query[i].j2;
        qs.push_back(i);
    }
    bs(0, cnt - 1, qs, 0);
    for (i = 1; i <= q; i++)
        cout << query[i].ans << "\n";
}