Cod sursa(job #2978534)

Utilizator xXoctavianXxStanescu Matei Octavian xXoctavianXx Data 13 februarie 2023 21:09:05
Problema Matrice 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.18 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 303;
const int qmax = 20003;
int NRMAX = -1;
int n,nr,it,m;
int matrix[nmax][nmax];
int toVector[nmax][nmax];
bool activ[nmax][nmax];

struct nodStr
{
    int i,j,tata,val,h;
    bool operator < (const nodStr &a) const
    {
        return val < a.val;
    }
} v[nmax*nmax];

struct queryStr
{
    int xs,ys,xf,yf,rasp,i;
} queries[qmax];

struct queryNodeStr
{
    int st,dr,h;
    queue<int> q;
};

void resetFather()
{
    it = nr;
    memset(activ,0,sizeof activ);
    for(int i=1; i<=nr; i++)
    {
        v[i].tata = i;
        v[i].h = 0;
    }
}

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

int tabs(int a)
{
    while(a!=v[a].tata) a = v[a].tata;
}

void uneste(int a, int b)
{
    int ta = tabs(a), tb = tabs(b);
    if(v[ta].h < v[tb].h)
    {
        swap(ta,tb);
        swap(a,b);
    }
    v[tb].tata = ta;
    v[ta].h += (v[ta].h == v[tb].h);
    int pas = a;
    while(pas!=ta)
    {
        int aux = v[pas].tata;
        v[pas].tata = ta;
        pas = aux;
    }
    pas = b;
    while(pas!=tb)
    {
        int aux = v[pas].tata;
        v[pas].tata = tb;
        pas = aux;
    }
}

bool ok(int i, int j)
{
    return 1<=i && i<=n && 1<=j && j<=n;
}

void add_until(int mij)
{
    for(; v[it].val>=mij && it>=1; it--)
    {
        activ[v[it].i][v[it].j] = 1;
        //cout<<"unesc "<<v[it].i<<" | "<<v[it].j<<" ("<<v[it].val<<")\n";
        for(int d=0; d<4; d++)
        {
            int pi = v[it].i + dx[d];
            int pj = v[it].j + dy[d];
            if(ok(pi,pj) && activ[pi][pj])
            {
                uneste(toVector[pi][pj],it);
            }
        }
    }
}

void bfs()
{
    queue<queryNodeStr> q;
    q.push({1,NRMAX,0});
    int prevH = 0;
    for(int i=1; i<=m; i++)
        q.front().q.push(i);
    while(!q.empty())
    {
        queryNodeStr curr = q.front();
        q.pop();
        int st = curr.st,dr = curr.dr, h = curr.h;
        //cout<<st<<" "<<(st+dr)/2<<" "<<dr<<"\n";
        //cout<<prevH<<"h"<<h<<"\n";
        if(prevH != h) resetFather();
        if(st==dr)
        {
            while(!curr.q.empty())
            {
                //cout<<":"<<curr.q.front()<<"\n";
                queries[curr.q.front()].rasp = st;
                curr.q.pop();
            }
        }
        else
        {
            int mij = (st + dr) / 2;
            queryNodeStr toLeft,toRight;
            toLeft = {st, mij, h + 1};
            toRight = {mij+1, dr, h + 1};
            add_until(mij+1);
            while(!curr.q.empty())
            {
                //cout<<":"<<curr.q.front()<<"\n";
                queryStr qry = queries[curr.q.front()];
                curr.q.pop();
                int t1 = tabs(toVector[qry.xs][qry.ys]);
                int t2 = tabs(toVector[qry.xf][qry.yf]);
                if(t1 == t2)
                {
                    //cout<<"cee  "<<v[t1].i<<" "<<v[t1].j<<"\n";
                    //cout<<"cee  "<<v[t2].i<<" "<<v[t2].j<<"\n";
                    //cout<<qry.xs<<" si "<<qry.ys<<" |na| "<<qry.xf<<" si "<<qry.yf<<"\n";
                    toRight.q.push(qry.i);
                }
                else toLeft.q.push(qry.i);
            }
            add_until(st);
            if(!toRight.q.empty())
                q.push(toRight);
            if(!toLeft.q.empty())
                q.push(toLeft);
        }
        prevH = h;
    }
}

int main()
{
    fin>>n>>m;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            fin>>matrix[i][j];
            v[++nr] = {i,j,0,matrix[i][j],0};
            NRMAX = max(NRMAX, matrix[i][j]);
        }
    }
    sort(v + 1, v + nr + 1);
    for(int i=1; i<=nr; i++)
    {
        toVector[v[i].i][v[i].j] = i;
    }
    resetFather();
    for(int i=1; i<=m; i++)
    {
        int xs,ys,xf,yf;
        fin>>xs>>ys>>xf>>yf;
        queries[i] = {xs,ys,xf,yf,0,i};
    }
    bfs();
    for(int i=1; i<=m; i++)
    {
        fout<<queries[i].rasp<<"\n";
    }
    return 0;
}