Cod sursa(job #2629979)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 23 iunie 2020 16:37:56
Problema Matrice 2 Scor 5
Compilator cpp-32 Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <fstream>
#include <vector>
#include <set>

using namespace std;

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

const int NMAX = 300;
const int VALMAX = 1e6;
const int QMAX = 20000;

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

vector < pair <int, int> > pos[VALMAX + 2];

int ans[QMAX + 2];

int p[NMAX + 2][NMAX + 2];
pair <int, int> a[NMAX * NMAX + 2];

set <int> l[NMAX * NMAX + 2];
set <int> r[NMAX * NMAX + 2];

bool active[NMAX * NMAX + 2];
int dad[NMAX * NMAX + 2];

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};

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)
    {
        if(l[p].size() + r[p].size() > l[q].size() + r[q].size())
        {
            dad[q] = p;
            while(!l[q].empty())
            {
                l[p].insert(*l[q].begin());
                l[q].erase(l[q].begin());
            }
            while(!r[q].empty())
            {
                r[p].insert(*r[q].begin());
                r[q].erase(r[q].begin());
            }
        }
        else
        {
            dad[p] = q;
            while(!l[p].empty())
            {
                l[q].insert(*l[p].begin());
                l[p].erase(l[p].begin());
            }
            while(!r[p].empty())
            {
                r[q].insert(*r[p].begin());
                r[p].erase(r[p].begin());
            }
        }
    }
}

void join(pair <int, int> x)
{
    active[p[x.first][x.second]] = true;

    for(int k = 0; k < 4; k++)
    {
        int xx = x.first + dx[k];
        int yy = x.second + dy[k];

        if(p[xx][yy] && active[p[xx][yy]])
            doJoin(p[x.first][x.second], p[xx][yy]);
    }

    int rt = Root(p[x.first][x.second]);

    if(mat[x.first][x.second] == 6)
        x.first++, x.first--;

    if(l[rt].size() > r[rt].size())
    {
        vector <int> toRemove;

        for(auto it : r[rt])
            if(r[rt].find(it) != r[rt].end())
                toRemove.push_back(it);

        for(auto it : toRemove)
        {
            ans[it] = mat[x.first][x.second];
            l[rt].erase(it);
            r[rt].erase(it);
        }
    }
    else
    {
        vector <int> toRemove;

        for(auto it : l[rt])
            if(r[rt].find(it) != r[rt].end())
                toRemove.push_back(it);

        for(auto it : toRemove)
        {
            ans[it] = mat[x.first][x.second];
            l[rt].erase(it);
            r[rt].erase(it);
        }
    }
}

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];
            pos[mat[i][j]].push_back({i, j});

            ++k;
            p[i][j] = k;
            a[k] = {i, j};

            dad[k] = k;
            active[k] = false;
        }

    for(int i = 1; i <= Q; i++)
    {
        int x, y, xx, yy;
        cin >> x >> y >> xx >> yy;

        l[p[x][y]].insert(i);
        r[p[xx][yy]].insert(i);
    }

    for(int i = VALMAX; i >= 1; i--)
        for(auto it : pos[i])
            join(it);

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

    return 0;
}