Cod sursa(job #1653746)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 16 martie 2016 15:38:54
Problema Matrice 2 Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <bits/stdc++.h>

using namespace std;

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

const int Nmax = 300 + 10;
const int Vmax = 1e6 + 10;
const int Qmax = 2 * 1e4 + 10;

int n , Q , val , i , j;
int T[Nmax*Nmax] , info[Nmax*Nmax];
int ans[Qmax];

bool bagat[Nmax*Nmax];

pair < int , int > m[Qmax];

vector < int > g[Vmax];
vector < int > keep[Nmax*Nmax];

int code(int x , int y);
void get(int z , int &x , int &y);

int multime(int node)
{
    if (node != T[node])
        T[node] = multime(T[node]);
    return T[node];
}

void uneste(int x , int y)
{
    x = multime(x); y = multime(y);
    T[y] = x;
    keep[x].push_back(y);
}

void sol(int x)
{
    for (auto &it : keep[x])
    {
        if (it != x)
        {
            sol(it);
            continue;
        }

        int q = info[it];
        if (!q) continue;
        if (ans[q] > 0) continue;

        int ff , ss;
        tie(ff , ss) = m[q];

        if (multime(ff) == multime(ss))
        {
            ans[q] = val;

            if (q == 5)
                cerr << multime(code(4,1)) << ' ' << multime(code(6,2));
        }
    }

}

bool limits(int x , int y)
{
    if (x < 1 || y < 1 || x > n || y > n)
        return 0;
    return 1;
}

int main()
{
    freopen("matrice2.in","r",stdin);
    freopen("matrice2.out","w",stdout);

    scanf("%d %d", &n, &Q);

    int maxx = 0;
    for (i = 1; i <= n; ++i)
        for (j = 1; j <= n; ++j)
        {
            int x;
            scanf("%d", &x);
            g[x].push_back(code(i,j));

            maxx = max(maxx , x);
        }

    for (i = 1; i <= Q; ++i)
    {
        int x0 , x1 , y0 , y1;
        scanf("%d %d %d %d", &x0 , &y0 , &x1 , &y1);

        info[code(x0,y0)] = i;
        info[code(x1,y1)] = i;

        m[i] = {code(x0,y0) , code(x1,y1)};
    }

    for (i = 1; i <= n * n; ++i)
        bagat[i] = 0, T[i] = i, keep[i].push_back(i);

    for (val = maxx; val ; --val)
    {
        for (auto &it : g[val])
        {
            int x , y;
            get(it , x , y);
            bagat[code(x,y)] = 1;

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

                if (!limits(xx,yy)) continue;
                if (!bagat[code(xx,yy)]) continue;

                uneste(it , code(xx,yy));
                sol(multime(it));
                int pula = 1;
            }
        }
    }

    for (i = 1; i <= Q; ++i)
        printf("%d\n", ans[i]);

    return 0;
}

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

void get(int z , int &x , int &y)
{
    if (z % n)
    {
        x = z / n + 1;
        y = z % n;
    }
    else
    {
        x = z / n;
        y = n;
    }
}