Cod sursa(job #2023324)

Utilizator ionanghelinaIonut Anghelina ionanghelina Data 18 septembrie 2017 19:04:44
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.82 kb
#include<bits/stdc++.h>
#define maxN 305
#define maxQ 20005
using namespace std;
int a[maxN][maxN];
pair<int,int> v[maxN*maxN];
bool cmp(pair<int,int> x,pair<int,int> y)
{
    return a[x.first][x.second]<a[y.first][y.second];
}

typedef struct tip
{
    int x,y,ind;
};
int sol[maxQ];
bool cmp2(tip a,tip b)
{
    return sol[a.ind]>sol[b.ind];
}
int n;
tip qry[maxQ];
class DSU
{
    private:
    int t[maxN*maxN];
    public:
    inline int GetRoot(int x)
    {
        int y;
        y=x;
        int z=x,aux;
        while(t[z]>=0)
        {
            z=t[z];
        }
        while(y!=z)
        {
            aux=t[y];
            t[y]=z;
            y=aux;
        }
        return z;
    }
    inline void Union(int x,int y)
    {
        int r1=GetRoot(x);
        int r2=GetRoot(y);
        if(r1==r2) return;
        if(r1!=r2)
        {
            if(t[r1]<t[r2])
            {
                t[r1]+=t[r2];
                t[r2]=r1;
            }
                else
            {
                t[r2]+=t[r1];
                t[r1]=r2;
            }
        }
    }
    inline void Clear()
    {
      //  memset(t,0,sizeof(t));
        for(int i=1;i<=n*n;i++) t[i]=-1;
    }
};
DSU Set;
int q;
int d[5][5];
inline void Scheme()
{
    d[1][1]=-1;
    d[1][2]=0;
    d[2][1]=1;
    d[2][2]=0;
    d[3][1]=0;
    d[3][2]=-1;
    d[4][1]=0;
    d[4][2]=1;

    for(int i=0;i<=n+1;i++)
        a[0][i]=a[n+1][i]=a[i][0]=a[i][n+1]=-1;
}
inline void Solve(int step)
{
    Set.Clear();
    sort(qry+1,qry+q+1,cmp2);
    int pos;
    pos=n*n;
    for(int i=1;i<=q;i++)
    {
        while(pos && a[v[pos].first][v[pos].second]>=(sol[qry[i].ind]+step))
        {
            int node=(v[pos].first-1)*n+v[pos].second;
            for(int j=1;j<=4;j++)
            {
                int l,c;
                l=v[pos].first+d[j][1];
                c=v[pos].second+d[j][2];
                if(a[l][c]!=-1 && a[l][c]>=(sol[qry[i].ind]+step))
                    Set.Union(node,(l-1)*n+c);
            }
            pos--;
        }
        if(Set.GetRoot(qry[i].x)==Set.GetRoot(qry[i].y)) sol[qry[i].ind]+=step;
    }
}
int main()
{
    freopen("matrice2.in","r",stdin);
    freopen("matrice2.out","w",stdout);
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&a[i][j]);
            v[(i-1)*n+j]={i,j};
        }
    }
    Scheme();
    sort(v+1,v+n*n+1,cmp);
    Set.Clear();
    int xa,ya,xb,yb;
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
        qry[i]={(xa-1)*n+ya,(xb-1)*n+yb,i};
    }
    for(int step=1<<20;step;step>>=1)
    {
        Solve(step);
    }
    for(int i=1;i<=q;i++)
        printf("%d\n",sol[i]);
    return 0;
}