Cod sursa(job #1394212)

Utilizator ThomasFMI Suditu Thomas Thomas Data 20 martie 2015 09:26:51
Problema Matrice 2 Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <fstream>
#include <algorithm>
using namespace std;

#define NMax 305
#define MMax 90005
#define QMax 20005

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

int n,Q;

int M[NMax][NMax];
int nr;

struct noduri
{
    int x,y;

    bool operator < (const noduri &t) const
    {
        if(M[x][y] > M[t.x][t.y]) return true;
        return false;
    }
} nods[MMax];

struct query
{
    int a,b,c,d;
} qry[QMax];

int H;

int val[QMax];
int mn[QMax];
int ind[QMax];

bool cmp(int i, int j)
{
    //if(val[i] == val[j]) return mn[i] > mn[j]; else
    return val[i] > val[j];
}

pair<int,int> tata[NMax][NMax];

pair<int,int> AQuery(int a,int b)
{
    if(tata[a][b] == make_pair(a,b)) return make_pair(a,b);
    pair<int,int> z = tata[a][b];
    return tata[a][b] = AQuery(z.first,z.second);
}

void ABuild(pair<int,int> a, pair<int,int> b)
{
    tata[b.first][b.second] = a;
}

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

void solve(int step)
{
    int i,j;

    int X,Y;
    pair<int,int> q1,q2;

    int crtq = 1;
    int crt;

    for(i=1;i<=n;++i) for(j=1;j<=n;++j) tata[i][j] = make_pair(i,j);

    for(i=1;i<=nr;++i)
    {
        q1 = AQuery(nods[i].x,nods[i].y);

        for(dir=0;dir<4;++dir)
        {
            X = nods[i].x + dx[dir];
            Y = nods[i].y + dy[dir];
            if(M[nods[i].x][nods[i].y] <= M[X][Y])
            {
                q2 = AQuery(X,Y);
                if(q1 != q2) ABuild(q1,q2);
            }
        }

        if(M[nods[i].x][nods[i].y] != M[nods[i+1].x][nods[i+1].y])
        {
            for(j=crtq;j<=Q;++j)
            {
                crt = ind[j];
                if(val[crt] != M[nods[i].x][nods[i].y]) break;

                crtq++;

                q1 = AQuery(qry[crt].a, qry[crt].b);
                q2 = AQuery(qry[crt].c, qry[crt].d);

                if(q1 != q2) val[crt] -= step;
            }
        }
    }
}

int main()
{
    int i,j;

    f>>n>>Q;
    for(i=1;i<=n;++i) for(j=1;j<=n;++j)
    {
        f>>M[i][j];
        nods[++nr].x = i;
        nods[nr].y = j;
    }

    sort(nods+1,nods+nr+1);
    H = M[nods[1].x][nods[1].y];

    for(i=1;i<=Q;++i)
    {
        ind[i] = i;
        f>>qry[i].a>>qry[i].b>>qry[i].c>>qry[i].d;
        mn[i] = min(M[qry[i].a][qry[i].b],M[qry[i].c][qry[i].d]);
    }

    int step;
    for(step = 1;step<=H;step<<=1);step>>=1;

    while(step)
    {
        for(i=1;i<=Q;++i) val[i] += step;
        sort(ind+1,ind+Q+1,cmp);

        solve(step);

        step>>=1;
    }

    for(i=1;i<=Q;++i) g<<val[i]<<"\n";

    f.close();
    g.close();
	return 0;
}