Cod sursa(job #3351370)

Utilizator CarenaMironov Cezar Luca Carena Data 18 aprilie 2026 19:38:23
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.1 kb
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

ifstream in("matrice2.in");
ofstream out("matrice2.out");

const int NMAX=3e2+5;
int n, q, a[NMAX*NMAX], srt[NMAX*NMAX], depth[NMAX*NMAX], lift[17][NMAX*NMAX];
vector<int> adj[NMAX*NMAX];
int di[4]={1, -1, 0, 0},
    dj[4]={0, 0, 1, -1};

inline int idx(int i, int j)
{
    return n*i+j;
}

bool inmat(int i, int j)
{
    return (0<=i && i<n) && (0<=j && j<n);
}

bool cmpa(int x, int y)
{
    return a[x]>a[y];
}

struct DSU
{
    int p[NMAX*NMAX];
    
    void init()
    {
        for(int i=0;i<n*n;i++)
            p[i]=i;
    }
    
    int find(int u)
    {
        return (u==p[u])?u:p[u]=find(p[u]);
    }
    
    void merge(int u, int v)
    {
        int pu=find(u), pv=find(v);
        if(pu==pv)
            return;
        adj[u].push_back(pv);
        p[pv]=pu;
    }
}ds;

void DFS(int u, int pu)
{
    lift[0][u]=pu;
    for(int b=1;b<=16;b++)
        lift[b][u]=lift[b-1][u]==-1?-1:lift[b-1][lift[b-1][u]];
    
    for(auto v:adj[u])
    {
        depth[v]=depth[u]+1;
        DFS(v, u);
    }
}

int lca(int u, int v)
{
    int pas;
    if(depth[u]>depth[v])
        swap(u, v);
    
    pas=16;
    while(pas>=0)
    {
        if(lift[pas][v]!=-1 && depth[lift[pas][v]]>=depth[u])
            v=lift[pas][v];
        pas--;
    }
    if(u==v)
        return u;
    
    pas=16;
    while(pas>=0)
    {
        if(lift[pas][u]!=lift[pas][v])
        {
            u=lift[pas][u];
            v=lift[pas][v];
        }
        pas--;
    }
    return lift[0][u];
}

int main()
{
    in>>n>>q;
    for(int i=0;i<n*n;i++)
    {
        in>>a[i];
        srt[i]=i;
    }
    
    sort(srt, srt+n*n, cmpa);
    ds.init();
    for(int i=0;i<n*n;i++)
        for(int d=0;d<4;d++)
            if(inmat(srt[i]/n + di[d], srt[i]%n + dj[d]) &&  a[idx(srt[i]/n + di[d], srt[i]%n + dj[d])]>=a[srt[i]])
                ds.merge(srt[i], idx(srt[i]/n + di[d], srt[i]%n + dj[d]));
    
    DFS(ds.find(0), -1);
    while(q--)
    {
        int x1, y1, x2, y2; in>>x1>>y1>>x2>>y2;
        out<<a[lca(idx(x1-1, y1-1), idx(x2-1, y2-1))]<<'\n';
    }
    return 0;
}