Cod sursa(job #2662203)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 23 octombrie 2020 17:52:59
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <bits/stdc++.h>
#define DIM 310
#define DIMM 90010
using namespace std;

struct cell{
    int cod,val,x,y;
} v[DIMM];

struct queryy{
    int x,y,x2,y2,sol,poz;
} qry[DIMM];

int t[DIMM],a[DIM][DIM],ans[DIMM];
int di[] = {-1,1,0,0};
int dj[] = {0,0,-1,1};
int n,i,j,x,y,q,k;


inline int cmp (cell a, cell b){
    return a.val > b.val;
}

inline int cmp2 (queryy a, queryy b){
    return a.sol > b.sol;
}

inline int inmat (int i, int j){
    if (i >= 1 && j >= 1 && i <= n && j <= n)
        return 1;
    return 0;
}

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

int get_rad (int x){
    while (t[x] > 0)
        x = t[x];
    return x;
}

void _union (int x, int y){
    int radx = get_rad (x), rady = get_rad (y);
    if (radx != rady){
        if (t[radx] > t[rady])
            swap (radx,rady);
        t[radx] += t[rady];
        t[rady] = radx;
    }
}

void add (int idx, int val){
    int ic = v[idx].x, jc = v[idx].y;
    for (int dir=0;dir<=3;dir++){
        int iv = ic + di[dir];
        int jv = jc + dj[dir];
        if (inmat (iv,jv) && a[iv][jv] >= val)
            _union (v[idx].cod,cod(iv,jv));
    }
}

int main (){

    ifstream cin ("matrice2.in");
    ofstream cout ("matrice2.out");

    cin>>n>>q;
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++){
            cin>>a[i][j];
            v[++k] = {cod(i,j),a[i][j],i,j};
        }

    sort (v+1,v+k+1,cmp);

    for (i=1;i<=q;i++){
        cin>>qry[i].x>>qry[i].y>>qry[i].x2>>qry[i].y2;
        qry[i].poz = i;
    }


    for (int nr=(1<<20);nr;nr>>=1){ /// incerc sa adaug valoarea asta la toate query urile

        sort (qry+1,qry+q+1,cmp2);

        /// refac padurile in acelasi timp in care parcud query urile
        memset (t,-1,sizeof t);

        int idx = 1;

        for (int i=1;i<=q;i++){

            int val = qry[i].sol + nr;

            while (idx <= k && v[idx].val >= val){

                /// adaug celula asta in padure
                add (idx,val);
                idx++;

            }

            if (get_rad( cod(qry[i].x,qry[i].y) ) == get_rad(cod(qry[i].x2,qry[i].y2)))
                qry[i].sol += nr;
        }

    }

    for (i=1;i<=q;i++)
        ans[qry[i].poz] = qry[i].sol;

    for (i=1;i<=q;i++)
        cout<<ans[i]<<"\n";


    return 0;
}