Cod sursa(job #3351321)

Utilizator CarenaMironov Cezar Luca Carena Data 18 aprilie 2026 16:41:43
Problema Matrice 2 Scor 55
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.84 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <set>

using namespace std;

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

const int NMAX=3e2+1;
int n, q, a[NMAX*NMAX], srt[NMAX*NMAX], node[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];
    set<int> padj[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)
    {
        u=find(u), v=find(v);
        if(u==v)
            return;
        if(a[u]>a[v] || (a[u]==a[v] && padj[u].size()<padj[v].size()))
            swap(u, v);
        
        if(a[u]==a[v])
		{
            for(auto w:padj[v])
                padj[u].insert(w);
            padj[v].clear();
		}
        else
            padj[u].insert(v);
        p[v]=u;
    }
}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();
    int l=0, r=-1;
    while(l<n*n)
    {
        while(r<l || (r+1<=n*n && a[srt[r+1]]==a[srt[r]]))
        {
            r++;
            for(int d=0;d<4;d++)
                if(inmat(srt[r]/n + di[d], srt[r]%n + dj[d]))
                {
                    int ni=idx(srt[r]/n + di[d], srt[r]%n + dj[d]);
                    if(a[ni]>=a[srt[r]])
                        ds.merge(srt[r], ni);
                }
        }
        
        for(int k=l;k<=r;k++)
        {
            node[srt[k]/n][srt[k]%n]=ds.find(srt[k]);
            if(node[srt[k]/n][srt[k]%n]==srt[k])
                for(auto v:ds.padj[srt[k]])
                    adj[srt[k]].push_back(v);
        }
        
        l=r+1;
    }
    
    DFS(ds.find(0), -1);
    while(q--)
    {
        int x1, y1, x2, y2; in>>x1>>y1>>x2>>y2;
        out<<a[lca(node[x1-1][y1-1], node[x2-1][y2-1])]<<'\n';
    }
    return 0;
}