Cod sursa(job #525279)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 24 ianuarie 2011 19:01:23
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <stdio.h>
#include <algorithm>
#define Nmax 302
#define Qmax 20002

using namespace std;

struct father{
    int i,j;

    inline bool operator !=( const father &o ){
        return ( o.i != i || o.j != j );
    }
    inline bool operator ==( const father &o ){
        return ( o.i==i && o.j==j);
    }
};

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

int N,q;
int X1[Qmax],X2[Qmax],Y1[Qmax],Y2[Qmax];
int Q[Qmax],iq[Qmax],sol[Qmax];
father tt[Nmax][Nmax];
int a[Nmax][Nmax],rg[Nmax][Nmax],b[Nmax][Nmax];
int v[Nmax*Nmax],ind[Nmax*Nmax],X[Nmax*Nmax],Y[Nmax*Nmax];

inline father Find( int i,int j){
    father r,x,w;
    w.i=i; w.j=j;
    for( r=w; r != tt[r.i][r.j]; ) r=tt[r.i][r.j];

    for( ;w != tt[w.i][w.j]; ){
        x=tt[ w.i][ w.j];
        tt[ w.i][ w.j] =r;
        w=x;
    }
    return r;
}

inline void Unite( father f1, father f2 ){
    if( rg[f1.i][f1.j] > rg[f2.i][f2.j] )
        tt[f2.i][f2.j]=f1;
    else tt[f1.i][f1.j]=f2;

    if( rg[f1.i][f1.j] == rg[f2.i][f2.j] )
        rg[f2.i][f2.j]++;
}

inline int bun(int x,int y){
    return x>0 && y>0 && x<=N && y<=N && b[x][y];
}
inline int cmp2(int i,int j){
    return Q[i] > Q[j];
}

void search(){
    int step=1,i,j,v0,ii,k;
    while( (step<<1) <= v[ind[1]] ) step<<=1;
    for( ; step ; step>>=1){
        for(i=1;i<=N;++i)
            for(j=1;j<=N;++j) tt[i][j]=(father){i,j}, rg[i][j]=1,b[i][j]=0;

        for(i=1;i<=q;++i){
            Q[i]=sol[i]+step;
            iq[i]=i;
        }
        sort(iq+1,iq+q+1,cmp2);

        for(i=1, j=1;i<=v[0]; ){
            for( ; j<=q && Q[iq[j]] > v[ind[i]]; ++j )
                if( Find( X1[iq[j]],Y1[iq[j]] ) == Find( X2[iq[j]],Y2[iq[j]]) )
                    sol[iq[j]] += step;

            for( v0=v[ind[i]] ; v[ind[i]] == v0; ++i ){
                ii=ind[i]; b[X[ii]][Y[ii]]=1;
                for(k=0; k<4; ++k){
                    if( bun( X[ii]+dx[k],Y[ii]+dy[k] ) )
                    if( Find(X[ii],Y[ii]) != Find( X[ii]+dx[k],Y[ii]+dy[k] ) )
                        Unite( Find(X[ii],Y[ii]) , Find( X[ii]+dx[k],Y[ii]+dy[k] ) );
                }
            }
        }

        for( ; j<=q ; ++j )
             if( Find( X1[iq[j]],Y1[iq[j]] ) == Find( X2[iq[j]],Y2[iq[j]]) )
                 sol[iq[j]] += step;
    }
}

inline int cmp(int i,int j){
    return v[i] > v[j];
}

int main(){
    int i,j,x,mx=0;
    freopen("matrice2.in","r",stdin);
    freopen("matrice2.out","w",stdout);
    scanf("%d%d",&N,&q);
    for(i=1;i<=N;++i)
        for(j=1;j<=N;++j){
            scanf("%d",&x),mx=mx > x ? mx:x;
            a[i][j]=x;
            v[++v[0]]=x;
            X[v[0]]=i; Y[v[0]]=j;
            ind[v[0]]=v[0];
        }
    sort(ind+1,ind+v[0]+1,cmp);
    for(i=1;i<=q;++i){
        scanf("%d%d%d%d",&X1[i],&Y1[i],&X2[i],&Y2[i]);
        Q[i]=i;
    }

     search();

    for(i=1;i<=q;++i) printf("%d\n",sol[i]);
    fclose(stdin); fclose(stdout);
    return 0;
}