Cod sursa(job #2717296)

Utilizator valentinchipuc123Valentin Chipuc valentinchipuc123 Data 7 martie 2021 00:07:30
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <bits/stdc++.h>

using namespace std;

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

int n,q,nr=0,tata[305*305],grd[305*305];
int di[4]= {1,-1,0,0};
int dj[4]= {0,0,1,-1};

bool fost[305][305];

struct muchii
{
    int va,nod;
} mch[305*305];

struct query
{
    int a,b,c,d,ind,ps;
} pct[20005],aux1[20005],aux2[20005];

void adauga(int val,int nods)
{
    nr++;
    mch[nr].va=val;
    mch[nr].nod=nods;
}

bool compare(query a,query b)
{
    return a.ps>b.ps;
}

bool ordine(query a,query b)
{
    return a.ind<b.ind;
}

bool cmp(muchii a,muchii b)
{
    return a.va>b.va;
}

bool valid(int x,int y)
{
    if(x<1||y<1||x>n||y>n) return 0;
    if(fost[x][y]==0) return 0;

    return 1;
}

int get_father(int k)
{
    if(tata[k]==0) return k;
    else
    {
        int x=get_father(tata[k]);
        tata[k]=x;
        return x;
    }
}

void leaga(int x,int y)
{
    if( x==y ) return;

    if( grd[x]>grd[y] ) tata[y]=x;
    if( grd[y]>grd[x] ) tata[x]=y;
    if( grd[x]==grd[y] ) grd[x]++,tata[y]=x;
}

void unim(int nod)
{
    int x,y;
    if(nod%n==0) y=n;
    else y=nod%n;
    x=(nod-y)/n+1;

    fost[x][y]=1;

    for(int directie=0; directie<4; directie++)
    {
        int ni=x+di[directie];
        int nj=y+dj[directie];

        if( valid(ni,nj) )
        {
            int nods=nj+(ni-1)*n;
            int father1=get_father(nods);
            int father2=get_father(nod);

            leaga(father1,father2);
        }

    }

}

void restore()
{
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            fost[i][j]=0,grd[j+(i-1)*n]=0,tata[j+(i-1)*n]=0;
}

int main()
{
    f>>n>>q;

    for(int i=1; i<=n; i++)
    {
        int x;
        for(int j=1; j<=n; j++)
        {
            f>>x;
            adauga(x,j+(i-1)*n);
        }
    }
    sort(mch+1,mch+nr+1,cmp);

    for(int i=1; i<=q; i++)
    {
        int x,y,z,t;
        f>>x>>y>>z>>t;
        pct[i].a=x;
        pct[i].c=z;
        pct[i].b=y;
        pct[i].d=t;
        pct[i].ind=i;
        pct[i].ps=0;
    }

    int pas=(1<<19),poz,nr1,nr2;

    while(pas)
    {
        poz=1;
        nr1=nr2=0;
        restore();

        for(int i=1; i<=q; i++)
        {
            while( poz<=nr && mch[poz].va>=pct[i].ps+pas )
            {
                unim(mch[poz].nod);
                poz++;
            }

            int father1=get_father(pct[i].b+(pct[i].a-1)*n);
            int father2=get_father(pct[i].d+(pct[i].c-1)*n);

            if(father1==father2)
                pct[i].ps+=pas,aux1[++nr1]=pct[i];
            else
                aux2[++nr2]=pct[i];

        }
        merge(aux1+1,aux1+nr1+1,aux2+1,aux2+nr2+1,pct+1,compare);
        pas/=2;
    }

    sort(pct+1,pct+q+1,ordine);

    for(int i=1;i<=q;i++) g<<pct[i].ps<<'\n';
}