Cod sursa(job #2627722)

Utilizator CraniXortDumitrescul Eduard CraniXort Data 12 iunie 2020 10:41:19
Problema Matrice 2 Scor 15
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <bits/stdc++.h>
#define maxn 305
#define maxdim 90005

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

int rank[maxdim];
int parent[maxdim];

void makeSet (int node){
    rank[node] = 1;
    parent[node] = node;
}

int findSet (int node){
    if (parent[node] == node)
        return node;
    return parent[node] = findSet (parent[node]);
}

void unionSets (int node1, int node2){
    node1 = findSet(node1);
    node2 = findSet(node2);

    if (node1 == node2)
        return;

    if (rank[node1] < rank[node2])
        std::swap (node1, node2);

    parent[node2] = node1;
    if (rank[node1] == rank[node2])
        rank[node1] ++;
}


struct Node{
    int x, y;
    int val, ind;
}v[maxdim];

bool nodeSort (Node a, Node b){
    return a.val > b.val;
}

int ans[maxdim];
int mat[maxn][maxn];

struct Query{
    int a, b;
}query[maxdim];

int left[maxdim], right[maxdim];
std::map <int, std::vector<int>> middle;

void binarySearch (int n, int Q){
    middle.clear();
    int max = 0, i, x, y, pos;
    for (i=0; i<Q; i++)
        middle[(left[i]+right[i])/2].push_back (i);

    for (i=0; i<n*n; i++){
        makeSet (i);
        max = std::max (max, v[i].val);
    }

    i = 0;
    for (int mid=max; mid>=0; mid--){
        for (; i<n*n and v[i].val >= mid; i++){
            x = v[i].x;
            y = v[i].y;
            pos = v[i].ind;
            if (x > 0 and mat[x-1][y] >= mid) unionSets (pos, pos-n);
            if (y > 0 and mat[x][y-1] >= mid) unionSets (pos, pos-1);
            if (x < n-1 and mat[x+1][y] >= mid) unionSets (pos, pos+n);
            if (y < n-1 and mat[x][y+1] >= mid) unionSets (pos, pos+1);
        }

        for (auto i: middle[mid]){
            if (findSet(query[i].a) == findSet(query[i].b))
                left[i] = mid + 1;
            else
                right[i] = mid - 1;
        }
        middle[mid].clear();
    }
}

int main()
{
    int n, Q, i, j, x, y, max=0;
    fin >> n >> Q;
    for (i=0; i<n; i++){
        for (j=0; j<n; j++){
            v[i*n+j].x = i;
            v[i*n+j].y = j;
            v[i*n+j].ind = i*n+j;
            fin >> v[i*n+j].val;
            mat[i][j] = v[i*n+j].val;
            max = std::max (max, mat[i][j]);
        }
    }

    std::sort (v, v+n*n, nodeSort);

    for (i=0; i<Q; i++){
        fin >> x >> y; x--; y--;
        query[i].a = x * n + y;
        fin >> x >> y; x--; y--;
        query[i].b = x * n + y;
        left[i] = 0;
        right[i] = max;
    }

    while (max){
        binarySearch(n, Q);
        max /= 2;
    }


    for (i=0; i<Q; i++)
        fout << (left[i]+right[i])/2 << '\n';

    return 0;
}