Cod sursa(job #1228106)

Utilizator touristGennady Korotkevich tourist Data 12 septembrie 2014 17:27:21
Problema Matrice 2 Scor 35
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.22 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#define Nmax 305
#define Qmax 20005
#define Vmax 1000005

using namespace std;

int N,Q,a[Nmax][Nmax],pad[Nmax*Nmax],MaxVal,MinVal=Vmax,sol[Qmax],nrmijl,nrauxi,nrinter;
int dx[]={-1,0,1, 0};
int dy[]={ 0,1,0,-1};

struct middle
{
    int mij,nr;
    bool operator < (const middle &A) const
    {
        return mij<A.mij;
    }
};
middle mijl[Qmax];

struct interval
{
    int left,right,st,dr;
};
interval inter[Qmax],auxi[Qmax];

struct cell
{
    int lin,col;
};
vector <cell> L[Vmax];

struct quer
{
    int l1,c1,l2,c2,poz;
};
quer v[Qmax],bune[Qmax],rele[Qmax];

inline int Findpoz(int lin, int col)
{
    return (lin-1)*N+col;
}

inline int Find(int a)
{
    int rad,i=a;
    while(pad[a]>0)
        a=pad[a];
    rad=a;
    while(pad[i]>0)
    {
        a=pad[i];
        pad[i]=rad;
        i=a;
    }
    return rad;
}

inline void Unite(int a, int b)
{
    pad[a]+=pad[b];
    pad[b]=a;
}

inline void Solve()
{
    int x,p=nrmijl,t,lin,col,lin1,col1,i,t1,t2,aux,nrbune,nrrele,paux;
    vector <cell> ::iterator it;
    for(i=1;i<=N*N;++i) pad[i]=-1;
    for(x=MaxVal,nrauxi=0;x>=MinVal && p;--x)
    {
        for(it=L[x].begin();it!=L[x].end();++it)
        {
            lin=it->lin; col=it->col;
            for(t=0;t<4;++t)
            {
                lin1=lin+dx[t]; col1=col+dy[t];
                if(lin1<1 || lin1>N || col1<1 || col1>N) continue;
                if(a[lin1][col1]>=x)
                {
                    t1=Find(Findpoz(lin,col));
                    t2=Find(Findpoz(lin1,col1));
                    if(t1!=t2)
                        Unite(t1,t2);
                }
            }
        }
        if(x==mijl[p].mij)
        {
            aux=mijl[p].nr;
            nrbune=nrrele=0;
            for(i=inter[aux].left;i<=inter[aux].right;++i)
                if(Find(Findpoz(v[i].l1,v[i].c1))!=Find(Findpoz(v[i].l2,v[i].c2)))
                    rele[++nrrele]=v[i];

            for(i=inter[aux].left;i<=inter[aux].right;++i)
                if(Find(Findpoz(v[i].l1,v[i].c1))==Find(Findpoz(v[i].l2,v[i].c2)))
                {
                    sol[v[i].poz]=mijl[p].mij;
                    bune[++nrbune]=v[i];
                }
            paux=inter[aux].left;
            for(i=1;i<=nrrele;++i)
                v[paux++]=rele[i];
            for(i=1;i<=nrbune;++i)
                v[paux++]=bune[i];
            if(nrrele)
            {
                ++nrauxi;
                auxi[nrauxi].left=inter[aux].left;
                auxi[nrauxi].right=inter[aux].left+nrrele-1;
                auxi[nrauxi].st=inter[aux].st;
                auxi[nrauxi].dr=mijl[p].mij-1;
            }
            if(nrbune)
            {
                ++nrauxi;
                auxi[nrauxi].left=inter[aux].left+nrrele;
                auxi[nrauxi].right=inter[aux].right;
                auxi[nrauxi].st=mijl[p].mij+1;
                auxi[nrauxi].dr=inter[aux].dr;
            }
            --p;
        }
    }
    nrinter=nrauxi;
    for(i=1;i<=nrauxi;++i)
        inter[i]=auxi[i];
}

int main()
{
    int i,j,gata=0;
    cell w;
    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", &a[i][j]);
            w.lin=i; w.col=j;
            L[a[i][j]].push_back(w);
            MaxVal=max(MaxVal,a[i][j]);
            MinVal=min(MinVal,a[i][j]);
        }
    for(i=1;i<=Q;++i)
    {
        scanf("%d%d%d%d", &v[i].l1,&v[i].c1,&v[i].l2,&v[i].c2);
        v[i].poz=i;
    }
    nrinter=1;
    inter[1].left=1; inter[1].right=Q; inter[1].st=MinVal; inter[1].dr=MaxVal;
    while(!gata)
    {
        gata=1; nrmijl=0;
        for(i=1;i<=nrinter;++i)
            if(inter[i].st<=inter[i].dr)
            {
                gata=0;
                ++nrmijl;
                mijl[nrmijl].mij=(inter[i].st+inter[i].dr)/2;
                mijl[nrmijl].nr=i;
                sort(mijl+1,mijl+nrmijl+1);
            }
        if(!gata)
            Solve();
    }
    for(i=1;i<=Q;++i)
        printf("%d\n", sol[i]);
    return 0;
}