Cod sursa(job #1994871)

Utilizator GabiTulbaGabi Tulba-Lecu GabiTulba Data 26 iunie 2017 14:07:38
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.81 kb
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
 
#define INF 2140000000
#define MaxN 305
#define MaxQ 200000
#define pi 3.1415926535897932384626433832795
 
using namespace std;
 
FILE *IN,*OUT;
 
int N,Q,Last[MaxQ],Max=0,pos=0;
struct spec
{
    int fx,fy,value;
}Mat[MaxN][MaxN];
struct spec2
{
    int value,x,y;
}l[MaxN*MaxN];
struct query
{
    int x1,y1,x2,y2,pos;
};
vector <query> Quest;
bool cond(spec2 a,spec2 b)
{
    return a.value>b.value;
}
queue <pair<pair<int,int>,vector<query> > > Queue;
void Reinitialize()
{
    pos=0;
    for(int i=1;i<=N;i++)    
        for(int j=1;j<=N;j++)
            Mat[i][j].fx=i,Mat[i][j].fy=j;
}
pair<int,int>find(int x,int y)
{
    pair<int,int>orig;
    orig.first=x,orig.second=y;
    while(Mat[x][y].fx!=x||Mat[x][y].fy!=y)
    {
        int ax=Mat[x][y].fx,ay=Mat[x][y].fy;
        x=ax,y=ay;
    }
    while(orig.first!=x||orig.second!=y)
    {
        int ax=Mat[orig.first][orig.second].fx,ay=Mat[orig.first][orig.second].fy;
        Mat[orig.first][orig.second].fx=x;
        Mat[orig.first][orig.second].fy=y;
        orig.first=ax,orig.second=ay;
    }
    return make_pair(x,y);
}
void Add(spec2 point)
{
    int X=point.x,Y=point.y,V=point.value;
    if(Mat[X][Y].fx!=X||Mat[X][Y].fy!=Y)
        return;
    if(X>1&&Mat[X-1][Y].value>=V)
    {
        pair<int,int> f=find(X-1,Y);
        Mat[f.first][f.second].fx=X;
        Mat[f.first][f.second].fy=Y;
    }
    if(Y>1&&Mat[X][Y-1].value>=V)
    {
        pair<int,int> f=find(X,Y-1);
        Mat[f.first][f.second].fx=X;
        Mat[f.first][f.second].fy=Y;
    }
    if(X<N&&Mat[X+1][Y].value>=V)
    {
        pair<int,int> f=find(X+1,Y);
        Mat[f.first][f.second].fx=X;
        Mat[f.first][f.second].fy=Y;
    }
    if(Y<N&&Mat[X][Y+1].value>=V)
    {
        pair<int,int> f=find(X,Y+1);
        Mat[f.first][f.second].fx=X;
        Mat[f.first][f.second].fy=Y;
    }
}
int main() {
 
    IN=fopen("matrice2.in","r");
    OUT=fopen("matrice2.out","w");
 
    fscanf(IN,"%d%d",&N,&Q);
 
    for(int i=1;i<=N;i++)
        for(int j=1;j<=N;j++)
        {
            fscanf(IN,"%d",&Mat[i][j].value);
            Mat[i][j].fx=i;
            Mat[i][j].fy=j;
            l[(i-1)*N+j].value=Mat[i][j].value;
            l[(i-1)*N+j].x=i;
            l[(i-1)*N+j].y=j;
            Max=max(Max,Mat[i][j].value);
        }
    sort(l+1,l+1+N*N,cond);
    for(int i=1;i<=Q;i++)
    {
        query aux;
        fscanf(IN,"%d%d%d%d",&aux.x1,&aux.y1,&aux.x2,&aux.y2);
        aux.pos=i;
        Quest.push_back(aux);   
    }
    l[0].value=INF;
    Queue.push(make_pair(make_pair(Max,0),Quest));
    while(!Queue.empty())
    {
        int L=Queue.front().first.first;
        int R=Queue.front().first.second;
        int Mid=(R+L)>>1;
        vector<query> left,right;
        if(l[pos].value<Mid)
            Reinitialize();
        while(l[pos+1].value>Mid)
            Add(l[++pos]);
        for(int i=0;i<Queue.front().second.size();i++)
        {
            query aux=Queue.front().second[i];
            if(find(aux.x1,aux.y1)==find(aux.x2,aux.y2))
                left.push_back(aux);
            else right.push_back(aux);
        }
        if(L-R<=1)
        {
            for(int i=0;i<left.size();i++)
                Last[left[i].pos]=L;
            for(int i=0;i<right.size();i++)
                Last[right[i].pos]=R;
        }
        else
        {
            if(!left.empty())
                Queue.push(make_pair(make_pair(L,Mid+1),left));
            if(!right.empty())
                Queue.push(make_pair(make_pair(Mid,R),right));
        }
        Queue.pop();
    }
    for(int i=1;i<=Q;i++)
        fprintf(OUT,"%d\n",Last[i]);
    return 0;
}