Cod sursa(job #1408415)

Utilizator heracleRadu Muntean heracle Data 30 martie 2015 00:31:44
Problema Matrice 2 Scor 0
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.53 kb
#include <cstdio>
#include <algorithm>
#include <cstring>

FILE* in=fopen("matrice2.in","r");
FILE* out=fopen("matrice2.out","w");

const int Q=305,W=20007;

struct point{
    int val;
    int x,y;
} a[Q*Q];

int last=0;

int v[Q][Q];
int who[Q][Q];

int n,q;

int up[Q*Q],s[Q*Q];

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

int uper(int x)
{
    if(up[x]==0)
        return x;
    up[x]=uper(up[x]);
}

int max(int a, int b)
{
    return a>b?a:b;
}

void unio(int a, int b)
{
    if(a==b)
        return;

    if(s[a]>s[b])
    {
        up[b]=a;
    }
    if(s[a]<s[b])
        up[a]=b;
    if(s[a]==s[b])
    {
        up[a]=b;
        s[b]++;
    }
}

void make_inchidere(int p)
{
    if(p>n*n)
        return;

    for(int i=last+1; i<=p; i++)
    {
        s[i]=1;
        for(int k=0; k<4; k++)
        {
            if(v[a[i].x+dx[k]][a[i].y+dy[k]]>=v[a[i].x][a[i].y] && s[who[a[i].x+dx[k]][a[i].y+dy[k]]]!=0 )
            {
                unio(uper(i),uper(who[a[i].x+dx[k]][a[i].y+dy[k]]));
            }
        }
    }
    last=p;
}

void reset_inchidere()
{
    last=0;
    memset(up,0,sizeof up);
    memset(s,0,sizeof s);
}




int nr;

bool cmp(const point &a, const point &b)
{
    return a.val>b.val;
}




struct query{
    int ax,ay,bx,by;
    int where;
    int cont;
} t[W];

bool cmp2(const query &a, const query &b)
{
    return a.where<b.where;
}


int rez[W];

int main()
{
    fscanf(in,"%d%d",&n,&q);

    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            fscanf(in,"%d",&v[i][j]);
            a[++nr].val=v[i][j];
            a[nr].x=i;
            a[nr].y=j;
        }
    }

    std::sort(a+1,a+n*n+1,cmp);

    for(int i=1; i<=q; i++)
    {
        fscanf(in,"%d%d%d%d",&t[i].ax,&t[i].ay,&t[i].bx,&t[i].by);
        t[i].cont=i;
    }


    for(int i=1; i<=n*n; i++)
        who[a[i].x ][a[i].y]=i;

    int part,act,nxt;

    for(int k=16; k>=0; k--)
    {
        reset_inchidere();

        part=1<<k;

        act=part;

        nxt=1;

        while(act<=n*n)
        {
            make_inchidere(act);

            while(nxt<=q && t[nxt].where<act)
            {
                if(uper(who[t[nxt].ax][t[nxt].ay])!=uper(who[t[nxt].bx][t[nxt].by]))
                {
                    t[nxt].where=act;
                }
                nxt++;
            }

            act+=part;
        }
        std::sort(t+1,t+q+1,cmp2);
    }

    for(int i=1; i<=q; i++)
    {
        rez[t[i].cont]=a[t[i].where+1].val;
    }

    for(int i=1; i<=q; i++)
    {
        fprintf(out,"%d\n",rez[i]);
    }




    return 0;
}