Cod sursa(job #2004036)

Utilizator silkMarin Dragos silk Data 24 iulie 2017 18:59:43
Problema Matrice 2 Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.96 kb
#include <cstdio>
#include <algorithm>
#define QMax 20000
#define NMax 300
#define lim 1e6
#define x first
#define y second
using namespace std;

struct matrix{int x,i,j;} v[NMax*NMax+1];
pair<int, int> tata[NMax+1][NMax+1];
pair<int, int> q[QMax+1];
int a[NMax+1][NMax+1];
int stiva[QMax+1];
int COADA[QMax+1];
int mid[QMax+1];
int res[QMax+1];
int qx1[QMax+1];
int qy1[QMax+1];
int qx2[QMax+1];
int qy2[QMax+1];
int N,Q;

int dirx[4] = {-1,0,1,0};
int diry[4] = {0,1,0,-1};

pair<int, int> Find(int x, int y)
{
    int xr=x,yr=y,x2,xp,yp;
    while(tata[xr][yr].x != xr || tata[xr][yr].y != yr) { x2 = xr; xr = tata[xr][yr].x; yr = tata[x2][yr].y; }
    while(tata[x][y].x != x || tata[x][y].y != y){
        xp = tata[x][y].x;
        yp = tata[x][y].y;
        tata[x][y] = {xr,yr};
        x = xp;
        y = yp;
    }

return {xr,yr};
}

inline void Union(int x1, int y1, int x2, int y2)
{
    pair<int, int> t1, t2;
    t1 = Find(x1,y1);
    t2 = Find(x2,y2);
    tata[t1.x][t1.y] = t2;
}

bool cmp(const matrix A, const matrix B)
{
    return A.x > B.x;
}

inline bool in(int x, int y)
{
    return (x >= 1 && x <= N && y >= 1 && y <= N);
}

int main(){
    FILE* fin = fopen("matrice2.in","r");
    FILE* fout = fopen("matrice2.out","w");

    int i,j,t,x,y,k,top,sf;

    fscanf(fin,"%d %d",&N,&Q);
    for(i = 1; i <= N; ++i)
        for(j = 1; j <= N; ++j)
        {
            fscanf(fin,"%d",&x);
            v[(i-1)*N+j] = {x,i,j};
            tata[i][j] = {i,j};
            a[i][j] = x;
        }

    sort(v+1,v+N*N+1,cmp);
    for(i = 1; i <= Q; ++i) fscanf(fin,"%d %d %d %d",&qx1[i],&qy1[i],&qx2[i],&qy2[i]);
    for(i = 1; i <= Q; ++i) q[i] = {1,lim};
    for(i = 1; i <= Q; ++i) COADA[i] = i;

    while(q[ COADA[1] ].x <= q[ COADA[1] ].y){
        top = sf = 0;
        t = 1;
        for(i = 1; i <= Q; ++i) mid[i] = (q[ COADA[i] ].x + q[ COADA[i] ].y) / 2;
        for(i = 1; i <= Q; i = j+1)
        {
            for(j = i; j <= Q && mid[j] == mid[j+1]; ++j);
            for(; t <= N*N && v[t].x >= mid[j]; ++t)
                for(k = 0; k < 4; ++k)
                {
                    x = v[t].i + dirx[k];
                    y = v[t].j + diry[k];
                    if(in(x,y) && a[x][y] >= mid[j]) Union(x,y,v[t].i,v[t].j);
                }

            for(k = i; k <= j; ++k)
            {
                x = COADA[k];
                if(Find(qx1[x], qy1[x]) == Find(qx2[x], qy2[x])){
                    res[x] = mid[k];
                    COADA[++sf] = x;
                    q[x].x = mid[k]+1;
                } else {
                    stiva[++top] = x;
                    q[x].y = mid[k]-1;
                }
            }

            while(top) COADA[++sf] = stiva[top--];
        }

        for(i = 1; i <= N; ++i)
            for(j = 1; j <= N; ++j)
            tata[i][j] = {i,j};
    }

    for(i = 1; i <= Q; ++i) fprintf(fout,"%d\n",res[i]);


return 0;
}