Cod sursa(job #1290225)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 10 decembrie 2014 23:06:41
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;
ifstream f("matrice2.in");
ofstream g("matrice2.out");
int N,M;
struct cell{
int x;
int y;
int val;
} Cell[305*305];
int F[305*305];
struct query
{
    int i,x1,x2,y1,y2,s;
} Query[20005];
int TT[305*305],R[305*305],ind;
bool Valid(int x,int y)
{
    return x>0 && y>0 && x<=N && y<=N;
}
int Father(int x)
{
    while(F[x]!=x)
        x=F[x];
    while(F[x]!=x)
        {
        int y=F[x];
        F[x]=x;
        x=y;
        }
    return x;
}
void Unite(int x,int y)
{
    if(R[x]<R[y])
        F[x]=y;
    else
        F[y]=x;
    if(R[x]==R[y])
        R[x]++;
}
void Read()
{
    int i;
    f>>N>>M;
    for(i=1;i<=N;i++)
       for(int j=1;j<=N;j++)
    {
        Cell[++ind].x=i;
        Cell[ind].y=j;
        f>>Cell[ind].val;
    }
    for(int i=1;i<=M;i++)
    {
        f>>Query[i].x1>>Query[i].y1>>Query[i].x2>>Query[i].y2;
        Query[i].i=i;
    }
}

int Code(int x,int y)
{
    return (x-1)*N+y;
}
void Insert(int x,int y)
{
    int poz=Code(x,y);
    F[poz]=poz;
    int dx[]={-1,0,0,1};
    int dy[]={0,-1,1,0};
    for(int i=0;i<4;i++)
    {
        if(Valid(x+dx[i],y+dy[i])==0)
            continue;
        if(F[Code(x+dx[i],y+dy[i])]==0)
            continue;
        if(Father(Code(x,y))!=Father(Code(x+dx[i],y+dy[i])))
            Unite(Father(Code(x,y)),Father(Code(x+dx[i],y+dy[i])));
    }
}
bool cmp(query a,query b)
{
    return a.s>b.s;
}
bool cmp2(query a,query b)
{
    return a.i<b.i;
}
bool cmp3(cell a,cell b)
{
    return a.val>b.val;
}
void binSearch()
{
    int step=30,left,right;sort(Cell+1,Cell+N*N+1,cmp3);
    for(step=30;step>=0;step--)
    {
        memset(F,0,sizeof(F));
        sort(Query+1,Query+M+1,cmp);
        int i=1,j=1;
        for(j=1,i=1;i<=M;i++)
        {
            for(;j<=N*N;j++)
            {
                if(Query[i].s+(1<<step)<=Cell[j].val)
                    Insert(Cell[j].x,Cell[j].y);
                else
                    break;
            }

            if(F[Code(Query[i].x1,Query[i].y1)]!=0 && Father(Code(Query[i].x1,Query[i].y1))==Father(Code(Query[i].x2,Query[i].y2)))
               Query[i].s+=(1<<step);
        }
    }
    sort(Query+1,Query+M+1,cmp2);
}
int main()
{
    Read();
    binSearch();
    for(int i=1;i<=M;i++)
        g<<Query[i].s<<"\n";
    return 0;
}