Cod sursa(job #2680154)

Utilizator Chirac_MateiChiriac Matei Chirac_Matei Data 2 decembrie 2020 19:34:05
Problema Matrice 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4 kb
#include <bits/stdc++.h>

using namespace std;

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

struct drum
{
    int xs,ys,xf,yf;
};
struct qs
{
    int id, val;
    qs(int id, int val)
    {
        this->id=id;
        this->val=val;
    }
    bool operator<(qs b) const
    {
        return val<b.val;
    }
};
struct pos
{
    int val;
    pair<int, int> p;

    pos(int val, pair<int, int> p)
    {
        this->val=val;
        this->p=p;
    }
    bool operator<(pos b) const
    {
        return val>b.val;
    }
};

int n,q,maxi;
pair<int, int> dsu[305][305];
int sz[305][305];
bool on[305][305];

drum a[20005];
int st[20005];
int dr[20005];
int mij[20005];
int last[20005];
bool rez[20005];

vector<pos> v;

void dsu_init()
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            dsu[i][j]={i, j};
            on[i][j]=false;
            sz[i][j]=1;
        }
}
pair<int, int> dsu_par(int x, int y)
{
    if(dsu[x][y] != make_pair(x, y))
        dsu[x][y]=dsu_par(dsu[x][y].first, dsu[x][y].second);

    return dsu[x][y];
}
void dsu_merge(int a, int b, int c, int d)
{
    auto it=dsu_par(a, b);
    a=it.first;
    b=it.second;

    it=dsu_par(c, d);
    c=it.first;
    d=it.second;

    if(a==c && b==d)
        return;

    if(sz[a][b]>sz[c][d])
    {
        swap(a, c);
        swap(b, d);
    }

    dsu[a][b]={c, d};
    sz[c][d]+=sz[a][b];
}
void dsu_on(int i, int j)
{
    //cout<<"on "<<i<<' '<<j<<'\n';

    on[i][j]=true;

    if(on[i+1][j])
        dsu_merge(i, j, i+1, j);
    if(on[i-1][j])
        dsu_merge(i, j, i-1, j);
    if(on[i][j+1])
        dsu_merge(i, j, i, j+1);
    if(on[i][j-1])
        dsu_merge(i, j, i, j-1);
}
void solve(vector<qs> qv)
{
    dsu_init();
    for(auto it : v)
    {
        while(!qv.empty() && qv.back().val>it.val)
        {
            int id=qv.back().id;
            qv.pop_back();

            if(dsu_par(a[id].xs, a[id].ys) == dsu_par(a[id].xf, a[id].yf))
                rez[id]=true;
            else
                rez[id]=false;
        }

        dsu_on(it.p.first, it.p.second);
    }

    while(!qv.empty())
    {
        int id=qv.back().id;
        qv.pop_back();

        if(dsu_par(a[id].xs, a[id].ys) == dsu_par(a[id].xf, a[id].yf))
            rez[id]=true;
        else
            rez[id]=false;
    }
}
int main()
{
    /*
    n=5;
    dsu_on(1, 1);
    dsu_on(1, 2);
    dsu_on(1, 3);
    dsu_on(1, 4);
    dsu_on(1, 5);
    dsu_on(2, 5);
    dsu_on(3, 5);
    dsu_on(4, 5);
    dsu_on(5, 5);
    dsu_on(5, 4);
    dsu_on(5, 3);
    dsu_on(4, 3);
    dsu_on(3, 3);

    cout<<(dsu_par(1, 1) == dsu_par(3, 3));
    return 0;
    */

    fin>>n>>q;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            int x;
            fin>>x;
            maxi=max(maxi, x);
            v.push_back(pos(x, {i, j}));
        }

    sort(v.begin(), v.end());

    for(int i=1; i<=q; i++)
    {
        fin>>a[i].xs>>a[i].ys>>a[i].xf>>a[i].yf;
        st[i]=1;
        dr[i]=maxi;
    }

    bool ok=true;
    vector<qs> qv;
    while(ok)
    {
        ok=false;
        qv.clear();
        for(int i=1; i<=q; i++)
        {
            if(st[i]<=dr[i])
            {
                ok=true;
                mij[i]=(st[i]+dr[i])/2;
                qv.push_back(qs(i, mij[i]));
            }
        }

        sort(qv.begin(), qv.end());
        solve(qv);

        cout<<st[1]<<' '<<mij[1]<<' '<<dr[1]<<' '<<rez[1]<<'\n';

        for(int i=1; i<=q; i++)
        {
            if(st[i]<=dr[i])
            {
                if(rez[i])
                {
                    last[i]=mij[i];
                    st[i]=mij[i]+1;
                }
                else
                {
                    dr[i]=mij[i]-1;
                }
            }
        }
    }

    for(int i=1; i<=q; i++)
        fout<<last[i]<<'\n';
    return 0;
}