Cod sursa(job #2126186)

Utilizator cristina_borzaCristina Borza cristina_borza Data 9 februarie 2018 12:34:54
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.11 kb
#include <bits/stdc++.h>

#define se second
#define fi first

using namespace std;

ifstream f ("matrice2.in");
ofstream g ("matrice2.out");

const int Vmax = 1e6 + 5;
const int Dim = 5e5 + 5;

int mat[ 500 ][ 500 ], ind[ 500 ][ 500 ];
int ans[ Dim ], p[ Dim ], w[ Dim ];
int n, t, nr;

bool use[ 500 ][ 500 ];

pair <pair <int, int>, pair <int, int> > q[ Dim ];
pair <int, int> qw[ Dim ], aux[ Dim ];

int find_tata (int node) {
    int cn = node;
    while (p[ cn ] != cn) {
        cn = p[ cn ];
    }

    while (node != cn) {
        int aux = p[ node ];
        p[ node ] = cn;
        node = aux;
    }

    return cn;
}

void uneste (int node1, int node2) {
    int t1 = find_tata (node1);
    int t2 = find_tata (node2);

    if (t1 == t2)
        return;

    if (w[ t1 ] > w[ t2 ]) {
        w[ t1 ] += w[ t2 ];
        p[ t2 ] = t1;
    }

    else {
        w[ t2 ] += w[ t1 ];
        p[ t1 ] = t2;
    }
}

void reset ( ) {
    memset (use, 0, sizeof (use));
    for (int i = 1; i <= nr; ++ i) {
        w[ i ] = 1;
        p[ i ] = i;
    }
}

bool cmp1 (pair <int, int> a, pair <int, int> b) {
    return a.fi > b.fi;
}

void cbin () {
    int pw;
    for (pw = 1; pw <= Vmax; pw <<= 1);

    while ( pw ) {
        reset ( );
        for (int i = 1; i <= t; ++ i) {
            qw[ i ].fi = ans[ i ] + pw;
            qw[ i ].se = i;
        }

        sort (qw + 1, qw + t + 1, cmp1);
        int pos = 1;

        for (int i = 1; i <= t; ++ i) {
            while (pos <= nr && mat[aux[ pos ].fi][aux[ pos ].se] >= qw[ i ].fi) {
                int l = aux[ pos ].fi;
                int c = aux[ pos ].se;

                use[ l ][ c ] = 1;
                if (use[l - 1][ c ] == 1) {
                    uneste (ind[l - 1][ c ], ind[ l ][ c ]);
                }

                if (use[l + 1][ c ] == 1) {
                    uneste (ind[l + 1][ c ], ind[ l ][ c ]);
                }

                if (use[ l ][c - 1] == 1) {
                    uneste (ind[ l ][c - 1], ind[ l ][ c ]);
                }

                if (use[ l ][c + 1] == 1) {
                    uneste (ind[ l ][c + 1], ind[ l ][ c ]);
                }

                ++pos;
            }

            if (find_tata (ind[q[ qw[ i ].se ].fi.fi][q[ qw[ i ].se ].fi.se]) == find_tata (ind[q[ qw[ i ].se ].se.fi][q[ qw[ i ].se ].se.se])) {
                ans[qw[ i ].se] = qw[ i ].fi;
            }
        }

        pw >>= 1;
    }
}

bool cmp (pair <int, int> a, pair <int, int> b) {
    return mat[ a.fi ][ a.se ] > mat[ b.fi ][ b.se ];
}

int main() {
    f >> n >> t;
    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= n; ++ j) {
            f >> mat[ i ][ j ];

            aux[ ++nr ] = {i, j};
            ind[ i ][ j ] = nr;
        }
    }

    sort (aux + 1, aux + nr + 1, cmp);
    for (int i = 1; i <= t; ++ i) {
        f >> q[ i ].fi.fi >> q[ i ].fi.se;
        f >> q[ i ].se.fi >> q[ i ].se.se;
    }

    cbin ( );
    for (int i = 1; i <= t; ++ i) {
        g << ans[ i ] << '\n';
    }

    return 0;
}