Cod sursa(job #321907)

Utilizator GavrilaVladGavrila Vlad GavrilaVlad Data 7 iunie 2009 18:41:46
Problema Matrice 2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

#define maxn 310
#define maxq 20010
#define pb push_back

struct punct
{
    long x;
    long y;
    long id;
};

long n, i, j, k, poz, q, l, p1, p2;
punct q1, q2, p[maxn*maxn];
long tata[maxn*maxn], euler[maxn*maxn*2], ad[maxn*maxn*2], st[maxn*maxn], r[19][maxn*maxn*2], sol[19][maxn*maxn*2], f[maxn*maxn];
long m[maxn][maxn], ind[maxn][maxn], fol[maxn][maxn];
vector <long> v[maxn*maxn];

const long d1[]={0, -1, 0, 1};
const long d2[]={-1, 0, 1, 0};

inline int cmp(punct a, punct b)
{
    return m[a.x][a.y]>m[b.x][b.y];
}

void c_conexe()
{
    long i, j, xx, yy, nod, aux;
    for(i=1; i<=n*n; i++)
    {
        tata[i]=i;
    }
    for(i=1; i<=n*n; i++)
    {
        fol[p[i].x][p[i].y]=1;
        for(j=0; j<4; j++)
        {
            xx=(p[i].x)+d1[j];
            yy=(p[i].y)+d2[j];
            if(xx && yy && xx<=n && yy<=n && fol[xx][yy])
            {
                nod=ind[xx][yy];
                while(tata[nod]!=nod)
                {
                    nod=tata[nod];
                }
                if(nod!=p[i].id)
                {
           //         printf("%d %d\n", nod, p[i].id);
                    tata[nod]=p[i].id;
                    v[p[i].id].pb(nod);
                    nod=ind[xx][yy];
                    while(tata[nod]!=nod)
                    {
                        aux=tata[nod];
                        tata[nod]=p[i].id;
                        nod=aux;
                    }
                }
            }
        }
    }
}

void df(long nod, long niv)
{
    long i, fiu;
  //  if(f[nod]) return;
    f[nod]=1;
    l++;
    st[nod]=l;
    euler[l]=nod;
    ad[l]=niv;
    for(i=0; i<v[nod].size(); i++)
    {
        fiu=v[nod][i];
        df(fiu, niv+1);
        l++;
        euler[l]=nod;
        ad[l]=niv;
    }
}

void rmq()
{
    long i, j, put, e;
    for(i=1; i<=l; i++)
    {
        r[0][i]=ad[i];
        sol[0][i]=euler[i];
    }
    for(put=1, e=1; put<=l; put*=2, e++)
    {
        for(i=1; i+put<=l; i++)
        {
            r[e][i]=r[e-1][i];
            sol[e][i]=sol[e-1][i];
            if(r[e-1][i+(put/2)]<r[e][i])
            {
                r[e][i]=r[e-1][i+(put/2)];
                sol[e][i]=sol[e-1][i+(put/2)];
            }
        //    printf("%d ", r[e][i]);
        }
    //    printf("\n");
    }
}
    
long raspunde(long poz1, long poz2)
{
    long put, e, s, nod, xx, yy;
    put=1;
    e=0;
    while(put*2<=poz2-poz1+1)
    {
        put*=2;
        e++;
    }       
    s=r[e][poz1];
    nod=sol[e][poz1];
 //   printf("%d ", poz2-put);
    if(r[e][poz2-put+1]<s)
    {
        s=r[e][poz2-put+1];
        nod=sol[e][poz2-put+1];
    }
  //  printf("%d ", nod);
    xx=nod/n+1;
    yy=nod%n;
    if(yy==0)
    {
        yy=n;
        xx--;
    }
  //  printf("%d %d\n", xx, yy);
    return m[xx][yy];
}

int main()
{
    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", &m[i][j]);
            poz=(i-1)*n+j;
            ind[i][j]=poz;
            p[poz].x=i;
            p[poz].y=j;
            p[poz].id=poz;
        }
    }
    
    sort(p+1, p+n*n+1, cmp);
    
    c_conexe();

    df(p[n*n].id, 1);
    
    rmq();
    
  //  printf("\n");
    
  /*  for(i=1; i<=n*n; i++)
    {
        printf("%d: ", i);
        for(j=0; j<v[i].size(); j++)
        {
            printf("%d ", v[i][j]);
        }
        printf("\n");
    }*/
    for(i=1; i<=q; i++)
    {
        scanf("%d%d%d%d", &q1.x, &q1.y, &q2.x, &q2.y);
        q1.id=(q1.x-1)*n+q1.y;
        q2.id=(q2.x-1)*n+q2.y;
        p1=min(st[q1.id], st[q2.id]);
        p2=max(st[q1.id], st[q2.id]);
      //  printf("%d %d\n", p1, p2);
        printf("%d\n", raspunde(p1, p2));
    }
    return 0;
}