Cod sursa(job #3206401)

Utilizator Robert_MitriRobert Mitri Robert_Mitri Data 22 februarie 2024 17:24:47
Problema Matrice 2 Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.62 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <map>
#include <unordered_map>
using namespace std;
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");

const int nmax = 300;

int mat[nmax+5][nmax+5];


int n,qsz;

map<pair<int,int>,int> nid;
int lid=0;

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

vector <int> v[nmax*nmax + 5];


int get_id(int i,int j)
{
    if(nid[ {i,j}]==0)
        nid[ {i,j}]=++lid;
    return nid[ {i,j}];
}
bool inmat(int i,int j)
{
    return i>=1 && i<=n && j>=1 && j<=n;
}

struct mel
{
    int x;
    int y;
    int val;
};

struct pr{
    int val;
    int nod;
};
struct query{
    int a;
    int b;
    int ind;
}q[20005];


vector <mel> nrm;
vector <pr> p;

struct comp{
vector <int> t;

    void clear()
    {
        t.clear();
        t.shrink_to_fit();
    }
    void resz(int sz)
    {
        t.resize(sz + 1);
        for(int j=0;j<=sz;j++)
            t[j]=-1;
    }
    comp()
    {

    }
    comp(int sz)
    {
        t.resize(sz + 1);
        for(int j=0;j<=sz;j++)
            t[j]=-1;
    }
    int rad(int x)
    {
        int r = x;
        for(;t[r]>0;r=t[r]);
        while(x!=r)
        {
            int aux = t[x];
            t[x]=r;
            x=aux;
        }
        return r;
    }
    void join(int x,int y)
    {
        int rx = rad(x);
        int ry = rad(y);
        if(rx==ry)
            return;
        if(-t[rx]<-t[ry])
            swap(rx,ry);
        t[rx]+=t[ry];
        t[ry]=rx;
    }
    bool same_c(int x,int y)
    {
        return rad(x)==rad(y);
    }

}c;


int sol[20005];


void bs(int st,int dr,vector<int>& qids,comp& pp,bool stc)
{
    if(st>=dr)
    {
        for(auto& i : qids)
            sol[q[i].ind]=p[dr].val;
        return;
    }
    int mid = (st+dr)/2;
    vector<int> a;
    vector<int> b;
    comp* c;
    if(stc)
    {
        for(int i = mid+1;i<=dr;i++)
            for(auto& j : v[p[i].nod])
                if(p[j].val >= p[mid+1].val)
                    pp.join(p[i].nod,p[j].nod);
        c=&pp;
    }
    else
    {
        comp cc(n*n);
        for(int i = mid+1;i<=n*n;i++)
            for(auto& j : v[p[i].nod])
                if(p[j].val >= p[mid+1].val)
                cc.join(p[i].nod,p[j].nod);
        c=&cc;
    }

    for(auto& bk : qids){
        if(c->same_c(q[bk].a,q[bk].b))
            b.push_back(bk);
        else
            a.push_back(bk);
    }
    qids.clear();
    qids.shrink_to_fit();
    if(!a.empty())
        bs(st,mid,a,*c,true);
    if(!b.empty())
        bs(mid+1,dr,b,*c,false);


}



int main()
{
    ios::sync_with_stdio(false);
    fin.tie(0);
    fout.tie(0);
    fin>>n>>qsz;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            fin>>mat[i][j];
            nrm.push_back({i,j,mat[i][j]});
        }
    sort(nrm.begin(),nrm.end(),[](const mel& a,const mel& b){return a.val<b.val;});
    p.push_back({-1,-1});
    for(auto& i : nrm)
        p.push_back({mat[i.x][i.y],get_id(i.x,i.y)});

    for(auto& i : nrm)
        for(int d=0; d<4; d++)
        {
            int l = dx[d]+i.x;
            int c = dy[d]+i.y;
            if(inmat(l,c))
                v[get_id(i.x,i.y)].push_back(get_id(l,c));
        }
    vector<int> vv;
    for(int i=1;i<=qsz;i++)
    {
        int x,y,x2,y2;
        fin>>x>>y>>x2>>y2;
        q[i]={get_id(x,y),get_id(x2,y2),i};
        vv.push_back(i);
    }

    c.resz(n*n);
    bs(1,n*n,vv,c,true);
    for(int i=1;i<=qsz;i++)
        fout<<sol[i]<<'\n';
}