Cod sursa(job #2693488)

Utilizator hhhhhhhAndrei Boaca hhhhhhh Data 6 ianuarie 2021 10:36:49
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.99 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
//#pragma GCC optimize("O3")
using namespace std;
using namespace __gnu_pbds;
auto random_address = [] { char *p = new char; delete p; return uint64_t(p); };
const uint64_t SEED = chrono::steady_clock::now().time_since_epoch().count() * (random_address() | 1);
mt19937_64 rng(SEED);
typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");
int n,q,v[305][305],st[20005],dr[20005],sol[20005],mij[20005];
bool use[20005];
bool put[305][305];
int comp[305][305];
vector<pii> nodes[100001];
int diri[5]={0,0,-1,1};
int dirj[5]={-1,1,0,0};
vector<pair<pii,int>> order;
struct query
{
    int x1,y1,x2,y2;
};
query qr[20005];
bool cmp(pii a, pii b)
{
    return a.second>b.second;
}
bool compnodes(pair<pii,int> a, pair<pii,int> b)
{
    return a.second>b.second;
}
void check(int num)
{
    int x1=qr[num].x1;
    int x2=qr[num].x2;
    int y1=qr[num].y1;
    int y2=qr[num].y2;
    if(comp[x1][y1]==comp[x2][y2])
        use[num]=1;
    else
        use[num]=0;
}
void merge_dsu(int c1,int c2)
{
    if(nodes[c1].size()<nodes[c2].size())
        swap(c1,c2);
    for(auto nod:nodes[c2])
    {
        nodes[c1].push_back(nod);
        comp[nod.first][nod.second]=c1;
    }
    nodes[c2].clear();
}
void add_node(int x, int y)
{
    for(int i=0;i<4;i++)
    {
        int lin=x+diri[i];
        int col=y+dirj[i];
        if(put[lin][col]==1&&comp[lin][col]!=comp[x][y])
            merge_dsu(comp[lin][col],comp[x][y]);
    }
}
void make_dsu(vector<pii> vals)
{
    for(auto i:vals)
        use[i.first]=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            int num=(i-1)*n+j;
            comp[i][j]=num;
            nodes[num].clear();
            nodes[num].push_back({i,j});
            put[i][j]=0;
        }
    int qpoz=0;
    for(int poz=0;poz<order.size();poz++)
    {
        int value=order[poz].second;
        int x=order[poz].first.first;
        int y=order[poz].first.second;
        while(qpoz<vals.size()&&vals[qpoz].second>value)
        {
            check(vals[qpoz].first);
            qpoz++;
        }
        add_node(x,y);
        put[x][y]=1;
        if(poz+1==order.size())
        {
            while(qpoz<vals.size())
            {
                check(vals[qpoz].first);
                qpoz++;
            }
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(0);
    fout.tie(0);
    fin>>n>>q;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            fin>>v[i][j];
            order.push_back({{i,j},v[i][j]});
        }
    sort(order.begin(),order.end(),compnodes);
    for(int i=1;i<=q;i++)
    {
        fin>>qr[i].x1>>qr[i].y1>>qr[i].x2>>qr[i].y2;
        st[i]=1;
        dr[i]=1e6;
    }
    while(true)
    {
        bool ok=0;
        vector<pii> trypls;
        for(int i=1;i<=q;i++)
        {
            if(st[i]<=dr[i])
            {
                ok=1;
                mij[i]=(st[i]+dr[i])/2;
                trypls.push_back({i,mij[i]});
            }
        }
        if(ok==0)
            break;
        sort(trypls.begin(),trypls.end(),cmp);
        make_dsu(trypls);
        for(auto j:trypls)
        {
            ll nr=j.first;
            if(use[nr]==1)
            {
                sol[nr]=max(sol[nr],mij[nr]);
                st[nr]=mij[nr]+1;
            }
            else
                dr[nr]=mij[nr]-1;
        }
    }
    for(int i=1;i<=q;i++)
        fout<<sol[i]<<'\n';
    return 0;
}