Cod sursa(job #2627715)

Utilizator CraniXortDumitrescul Eduard CraniXort Data 12 iunie 2020 09:41:01
Problema Matrice 2 Scor 15
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.78 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];

void binarySearch (int left, int right, int n, int Q){
    if (left > right)
        return;
    int mid = (left + right) / 2, i;
    for (int i=0; i<n*n; i++)
        makeSet(i);
    for (i=0; i<n*n and v[i].val >= mid; i++){
        int x = v[i].x;
        int y = v[i].y;
        int 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);
    }
    int lower=0, upper=0;
    for (i=0; i<Q; i++){
        if (ans[i] == 0 and findSet(query[i].a) == findSet(query[i].b)){
            ans[i] = mid;
            upper ++;
        }
        if (ans[i] == 0 and findSet(query[i].a) != findSet(query[i].b)){
            lower ++;
        }
        if (ans[i] != 0 and ans[i] < mid and findSet(query[i].a) == findSet(query[i].b)){
            ans[i] = mid;
            upper ++;
        }
        if (ans[i] != 0 and findSet(query[i].a) != findSet(query[i].b)){
            lower ++;
        }
    }

    if (lower)
        binarySearch(left, mid-1, n, Q);
    if (upper)
        binarySearch(mid+1, right, n, Q);
}

int main()
{
    int n, Q, i, j, x, y;
    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;
        }
    }

    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;
    }

    binarySearch(v[n*n-1].val, v[0].val, n, Q);

    for (i=0; i<Q; i++)
        fout << ans[i] << '\n';

    return 0;
}