Cod sursa(job #844993)

Utilizator stoicatheoFlirk Navok stoicatheo Data 30 decembrie 2012 11:29:25
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.07 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
 
#define NLen 0x200
#define QLen 0x8000
#define NumLen 0x100000
 
using namespace std;
 
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
 
int Mat[NLen][NLen];
 
char frq[NumLen];
int use[NumLen];
int G[NLen*NLen];
int aux[QLen];
int Sol[QLen];
 
int N;
int Q;
int last;
 
struct Point
{
    int sx,sy,fx,fy;
}P[QLen];
 
struct Position
{
    int value,idx;
}v[NLen*NLen],h[QLen];
 
inline bool Comp_v(const Position &a,const Position &b)
{
    return a.value<b.value;
}
 
inline bool Comp_h(const Position &a,const Position &b)
{
    return a.value>b.value;
}
 
inline int Convert(int a,int b)
{
    return (a-1)*N+b;
}
 
inline int root(int nod)
{
    if(G[nod]!=nod) G[nod]=root(G[nod]);
    return G[nod];
}
 
inline void unite(int x,int y)
{
    G[root(x)]=root(y);
}
 
inline void grow(int H)
{
   
    int i;
     
    for(i=last;i>0&&v[i].value>=H;--i)
    {
        int x=v[i].idx/N;
        int y=v[i].idx%N;
 
        if(y==0) y=N;
        else ++x;
 
        for(int j=0;j<4;++j)
            if(0<x+dx[j]&&x+dx[j]<=N&&
                0<y+dy[j]&&y+dy[j]<=N&&
                Mat[x+dx[j]][y+dy[j]]>=H)
            {
                unite(v[i].idx,Convert(x+dx[j],y+dy[j]));
            }
    }
 
    last=i;
}
 
int main()
{
    freopen("matrice2.in","r",stdin);
    freopen("matrice2.out","w",stdout);
 
    cin>>N>>Q;
     
    for(int i=1;i<=N;++i)
        for(int j=1;j<=N;++j)
            cin>>Mat[i][j];
 
    for(int i=1;i<=Q;++i)
        cin>>P[i].sx>>P[i].sy>>P[i].fx>>P[i].fy;

    for(int i=1;i<=N;++i)
        for(int j=1;j<=N;++j)
            frq[Mat[i][j]]=1;
 
    int M=0;
    for(int i=1;i<NumLen;++i)
        if(frq[i]) use[++M]=i;
 

 
    int L=0;
    for(int i=1;i<=N;++i)
        for(int j=1;j<=N;++j)
        {
            v[++L].value=Mat[i][j];
            v[L].idx=L;
        }
 
    sort(v+1,v+L+1,Comp_v);
 
    memset(h,0,sizeof(h));
    for(int i=1;i<=Q;++i) h[i].idx=i;
 
    int step;
    for(step=1;step<M;step*=2);
 
    for(;step;step/=2)
    {
       
        for(int i=1;i<=L;++i) G[i]=i;
 
        
        last=L;
 
       
 
        sort(h+1,h+Q+1,Comp_h);
 
       
        for(int i=1;i<=Q;++i) aux[i]=h[i].value;
 
        for(int i=1;i<=Q;++i)
            if(h[i].value+step<=M) 
            {
            
                if(i==1||h[i].value!=h[i-1].value) grow(use[h[i].value+step]);
 
            
                int ind=h[i].idx;
 
                int sx=P[ind].sx;
                int sy=P[ind].sy;
                int fx=P[ind].fx;
                int fy=P[ind].fy;
 
                int r_s=root(Convert(sx,sy));
                int r_f=root(Convert(fx,fy));
 
                if(r_s==r_f) aux[i]=h[i].value+step;
            }
 
  
        for(int i=1;i<=Q;++i) h[i].value=aux[i];
    }
 
    for(int i=1;i<=Q;++i)
        Sol[h[i].idx]=use[h[i].value];
 
    for(int i=1;i<=Q;++i) cout<<Sol[i]<<'\n';
 
    return 0;
}