Cod sursa(job #2697930)

Utilizator stefantagaTaga Stefan stefantaga Data 20 ianuarie 2021 14:38:30
Problema Matrice 2 Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("matrice2.in");
ofstream g("matrice2.out");
int n,q,v[305][305],elem[90005],i,j,maxim,lg,putere,parinte[90005],locusor,loc1,loc2,sol[90005],locul[90005];
pair <int,int> pozitie[90005];
int tata(int x)
{
    if (x!=parinte[x])
    {
        return tata(parinte[x]);
    }
    return x;
}
void uneste (int x,int y)
{
    x=tata(x);
    y=tata(y);
    parinte[x]=y;
}
bool compare (int a,int b)
{
    pair <int,int> poza=pozitie[a];
    pair <int,int> pozb=pozitie[b];
    return v[poza.first][poza.second]>v[pozb.first][pozb.second];
}
struct wow
{
    int x,y,x2,y2;
}query[20005];
bool compare2( int a,int b)
{
    return sol[a]<sol[b];
}
int val(int loc)
{
    pair <int,int> pozloc=pozitie[loc];
    return v[pozloc.first][pozloc.second];
}
bool interior (pair <int,int> loc)
{
    if (1<=loc.first&&loc.first<=n&&1<=loc.second&&loc.second<=n)
    {
        return 1;
    }
    return 0;
}
int dl[]={1,-1,0,0};
int dc[]={0,0,1,-1},nr;
int main()
{
    f>>n>>q;
    for (i=1;i<=n;i++)
    {
        for (j=1;j<=n;j++)
        {
            f>>v[i][j];
            nr++;
            pozitie[nr]={i,j};
            maxim=max(maxim,v[i][j]);
        }
    }
    for (i=1;i<=q;i++)
    {
        f>>query[i].x>>query[i].y>>query[i].x2>>query[i].y2;
    }
    for (i=1;i<=n*n;i++)
    {
        elem[i]=i;
    }
    sort (elem+1,elem+n*n+1,compare);
    lg=log2(maxim);
    putere=1;
    for (j=1;j<=lg+1;j++)
    {
        putere=putere*2;
    }
    for (;putere>=1;putere>>=1)
    {
        for (i=1;i<=n*n;i++)
        {
            parinte[i]=i;
        }
        for (i=1;i<=q;i++)
        {
            locul[i]=i;
        }
        sort (locul+1,locul+q+1,compare2);
        j=1;
        for (i=q;i>=1;i--)
        {
            int poz=locul[i];
            int valoare=sol[poz]+putere;

            while (j<=n*n&&val(elem[j])>=valoare)
            {
                pair <int,int> poz=pozitie[elem[j]];
                pair <int,int> poz2;
                for (int k=0;k<4;k++)
                {
                    poz2.first=poz.first+dl[k];
                    poz2.second=poz.second+dc[k];
                    int loc3=(poz2.first-1)*n+poz2.second;
                    if (interior(poz2)==1&&val(loc3)>=valoare)
                    {
                        locusor=(poz2.first-1)*n+poz2.second;
                        uneste(locusor,elem[j]);
                    }
                }
                j++;
            }
            loc1=(query[poz].x-1)*n+query[poz].y;
            loc2=(query[poz].x2-1)*n+query[poz].y2;
            if (tata(loc1)==tata(loc2))
            {
                sol[poz]=valoare;
            }
        }
    }
    for (i=1;i<=q;i++)
    {
        g<<sol[i]<<'\n';
    }
    return 0;
}