Cod sursa(job #2681889)

Utilizator vladth11Vlad Haivas vladth11 Data 7 decembrie 2020 12:16:06
Problema Matrice 2 Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define debug(x) cerr << #x << " " << x << "\n"
#define debug_with_space(x) cerr << #x << " " << x << " "

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair <ll, ll> pii;
typedef pair <ll, pii> piii;
typedef tree <pii, null_type, less <pii>, rb_tree_tag, tree_order_statistics_node_update> OST;

const ll NMAX = 301 * 301;
const ll INF = (1 << 16) - 1;
const ll MOD = 1000000007;
const ll BLOCK = 101;
const ll nr_of_bits = 20;

int mat[301][301];

struct ura {
    int i, j, val;
} a[NMAX];

int sol[NMAX], n;

vector <pii> updates;
struct intr {
    int a, b, c, d;
} queries[20001];

int l[20001];
int r[20001], q;
int minim[20001];

int cod(int i, int j) {
    return (i - 1) * n + j;
}

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

bool adaugat[NMAX];

bool cmp(ura a, ura b) {
    return a.val > b.val;
}

class DSU {
    int parent[NMAX], cnt[NMAX];
    int root(int x) {
        if(x == parent[x]) {
            return x;
        }
        return parent[x] = root(parent[x]);
    }
public:
    void merge(int x, int y) {
        x = root(x);
        y = root(y);
        if(x == y)
            return;
        if(cnt[x] > cnt[y])
            swap(x, y);
        cnt[y] += cnt[x];
        cnt[x] = 0;
        parent[x] = y;
    }
    void init() {
        for(int i = 1; i <= n * n; i++) {
            parent[i] = i;
            cnt[i] = 1;
        }
    }
    bool same(int x, int y) {
        return (root(x) == root(y));
    }
} dsu;

vector <int> check[NMAX];

void baga() {
    dsu.init();
    int i;
    for(i = 1; i <= updates.size(); i++){
        check[i].clear();
    }
    for(i = 1; i <= q; i++){
        int mid = (l[i] + r[i]) / 2;
        check[mid].push_back(i);
    }
    for(i = 0; i < updates.size(); i++){
        dsu.merge(updates[i].first, updates[i].second);
        for(auto x : check[i + 1]){
            if(dsu.same(cod(queries[x].a, queries[x].b), cod(queries[x].c, queries[x].d))){
                r[x] = i + 1 - 1;
            }else{
                l[x] = i + 1;
            }
        }
    }
}

int main() {
    ifstream cin("matrice2.in");
    ofstream cout("matrice2.out");
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int i, j;
    cin >> n >> q;
    for(i = 1; i <= n; i++) {
        for(j = 1; j <= n; j++) {
            int c = cod(i, j);
            cin >> a[c].val;
            a[c].i = i;
            a[c].j = j;
        }
    }
    sort(a + 1, a + n * n + 1, cmp);
    minim[0] = 2e9;
    for(i = 1; i <= n * n; i++) {
        adaugat[cod(a[i].i, a[i].j)] = 1;
        for(int d = 0; d < 4; d++) {
            int ni = a[i].i + dx[d];
            int nj = a[i].j + dy[d];
            if(ni >= 1 && ni <= n && nj >= 1 && nj <= n && adaugat[cod(ni,nj)]) {
                updates.push_back({cod(a[i].i, a[i].j), cod(ni, nj)});
                minim[updates.size()] = a[i].val;
            }
        }

    }
    for(i = 1; i <= q; i++) {
        cin >> queries[i].a >> queries[i].b >> queries[i].c >> queries[i].d;
        l[i] = 1;
        r[i] = updates.size();
    }

    for(i = 1; i <= nr_of_bits; i++) {
        baga();
    }
    for(i = 1; i <= q; i++){
        cout << minim[l[i] + 1] << "\n";
    }
    return 0;
}