Cod sursa(job #1156949)

Utilizator alexalghisiAlghisi Alessandro Paolo alexalghisi Data 28 martie 2014 09:57:09
Problema Matrice 2 Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>

#define DN 305
#define DM 20005
#define per pair<int,int>
#define x first
#define y second
using namespace std;

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

struct st{

    int x0,y0,x1,y1,val,ind;
    st(){
        val = 0;
    }
};

int x[DN][DN],sz = 0,n,m,cnt,nd[DN][DN],t[DN*DN],ad;
int ii[]={0,0,-1,1},jj[]={1,-1,0,0};
st q[DM];
per H[DN];

inline bool cmp(per A,per B){

    return x[A.x][A.y] > x[B.x][B.y];
}
inline bool cmp2(st A,st B){

    return A.val > B.val;
}
inline bool cmp3(st A,st B){

    return A.ind < B.ind;
}


void read(){

    f>>n>>m;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j){

            f>>x[i][j];
            H[++sz] = make_pair(i,j);
        }
    for(int i=1;i<=m;++i){

        f>>q[i].x0>>q[i].y0>>q[i].x1>>q[i].y1;
        q[i].ind = i;
    }
}

void init(){

    cnt = 0;
    ad = 1;
    memset(nd,0,sizeof(nd));
    for(int i=1;i<=n*n;++i) t[i] = i;
}

inline int find_t(int nod){

    int root = nod;
    while(root!=t[root])
        root = t[root];
    t[ nod ] = root;
    return root;
}

void unesc(int x,int y){

    t[ find_t(x) ] = t[ find_t(y) ];
}

void cupleaza(int x,int y){

    for(int t=0;t<4;++t)
        if(nd[x+ii[t]][y+jj[t]])
            unesc(nd[x][y] , nd[x+ii[t]][y+jj[t]]);
}


void solve(){

    /// sortez descrescator elementele matricii
    sort(H+1,H+n*n+1,cmp);

    for(int i=20;i>=0;--i){ /// caut bitii rezultatului

        sort(q+1,q+m+1,cmp2); /// sortez queryurile dupa val
        init();

        for(int ii = 1;ii<=m;++ii){

            for( ; ad<=n*n && x[ H[ad].x ][ H[ad].y ] >= (q[ii].val + (1<<i)) ; ++ad){

                nd[ H[ad].x ][ H[ad].y ] = ++cnt;
                cupleaza(  H[ad].x  ,  H[ad].y );
            }

            int t1 = find_t( nd [q[ii].x0][q[ii].y0] ) , t2 = find_t( nd[q[ii].x1][q[ii].y1] );
            if(t1 == t2 && t1)
                q[ii].val+=(1<<i);
        }
    }
}

void write(){

    sort(q+1,q+m+1,cmp3);
    for(int i=1;i<=m;++i)
        g<<q[i].val<<"\n";
}


int main()
{
    read();
    solve();
    write();

    return 0;
}