Cod sursa(job #2755512)

Utilizator tryharderulbrebenel mihnea stefan tryharderul Data 27 mai 2021 16:12:09
Problema Matrice 2 Scor 45
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.82 kb
#include <bits/stdc++.h>

using namespace std;

int n,nrq,hmax,Next;
int mat[303][303];
vector<pair<int,int> >nod;
vector<int>G[303*303];
int ans[20003];

int comp[303*303];

int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};

struct query{
    int a,b,poz;
};

vector<query>Q;

bool inside(int x,int y){
    return x>=1 && y>=1 && x<=n && y<=n;
}

int poz(int x,int y){
    return (x-1)*n+y;
}
void Reinit(){
    Next=0;
    for(int i=1;i<=n*n;i++){
        comp[i]=i;
    }
}

int Find(int x){
    int root=x;
    while(root!=comp[root]){
        root=comp[root];
    }
    while(x!=root){
        int aux=comp[x];
        comp[x]=root;
        x=aux;
    }
    return root;
}

void add(int x){
    for(auto y:G[x]){
        comp[Find(x)]=Find(y);
    }
}

int main()
{
    freopen("matrice2.in","r",stdin);
    freopen("matrice2.out","w",stdout);
    scanf("%d %d",&n,&nrq);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&mat[i][j]);
            hmax=max(hmax,mat[i][j]);
            comp[poz(i,j)]=poz(i,j);
            nod.push_back({mat[i][j],poz(i,j)});
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int dir=0;dir<4;dir++){
                int newx=i+dx[dir];
                int newy=j+dy[dir];
                if(inside(newx,newy) && mat[newx][newy]>=mat[i][j]){
                    G[poz(i,j)].push_back(poz(newx,newy));
                }
            }
        }
    }
    for(int i=1;i<=nrq;i++){
        int a,b,x,y;
        scanf("%d %d %d %d",&a,&b,&x,&y);
        Q.push_back({poz(a,b),poz(x,y),i});
    }
    sort(nod.rbegin(),nod.rend());
    queue<pair<pair<int,int>,vector<query> > >q;
    q.push( { {1,hmax},Q });
    Next=0;
    while(!q.empty()){
        int l=q.front().first.first;
        int r=q.front().first.second;
        vector<query>Left;
        vector<query>Right;
        vector<query>act=q.front().second;
        int mid=(l+r)/2;
        if(nod[Next].first<mid){
            Reinit();
        }
        while(nod[Next].first>mid){
            add(nod[Next].second);
            Next++;
        }
        for(auto x:act){
            if(Find(x.a)==Find(x.b)){
                Left.push_back(x);
            }else{
                Right.push_back(x);
            }
        }
        if(r-l<2){
            for(auto x:Left){
                ans[x.poz]=r;
            }
            for(auto x:Right){
                ans[x.poz]=l;
            }
        }else{
            if(Left.size()>0){
                q.push( { {mid+1,r},Left } );
            }
            if(Right.size()>0){
                q.push( { {l,mid},Right } );
            }
        }
        q.pop();
    }
    for(int i=1;i<=nrq;i++)
        printf("%d\n",ans[i]);


    return 0;
}