5255 2023. 04. 24 11:55:12 sztomi Hegyi levegő cpp17 Időlimit túllépés 90/100 3.078s 318344 KiB
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;

const int INF = 1e9+7;
const int MAXN = 500000;
const int MAXK = 20;

int valt_x[]{0, 0, 1, -1};
int valt_y[]{1, -1, 0, 0};


int n, m, q;
int pont_ertek[MAXN];

vector<int> graf[MAXN];

int szulo[MAXN];
int magas[MAXN];
int meret[MAXN];


struct lca_struct{
    int folott[MAXN][MAXK];

    void build(){
        int nx = n*m;
        for(int i = 0; i < nx; i++){
            if(szulo[i] != -1)
                folott[i][0] = szulo[i];
            else
                folott[i][0] = i;
        }

        for(int i = 1; i < MAXK; i++){
            for(int j = 0; j < nx; j++){
                folott[j][i] = folott[folott[j][i-1]][i-1];
            }
        }
    }

    int lca(int a, int b){
        if(magas[a] < magas[b]) swap(a, b);

        for(int i = MAXK-1; i >= 0; i--){
            if(magas[a] - (1<<i) >= magas[b]){
                a = folott[a][i];
            }
        }

        if(a == b) return b;

        for(int i = MAXK-1; i >= 0; i--){
            if(folott[a][i] != folott[b][i]){
                a = folott[a][i];
                b = folott[b][i];
            }
        }

        return folott[a][0];
    }
};

int hld_euler_ind[MAXN];
int hld_fej[MAXN];
vector<int> hld_euler_ertek;

void hld_dfs(int akt){
    hld_euler_ind[akt] = hld_euler_ertek.size();
    hld_euler_ertek.push_back(pont_ertek[akt]);
    int legn_gyerek = -1, legn_meret = -1;
    for(int kov : graf[akt]){
        if(meret[kov] > legn_meret){
            legn_gyerek = kov;
            legn_meret = meret[kov];
        }
    }

    if(legn_gyerek == -1) return;

    hld_fej[legn_gyerek] = hld_fej[akt];
    hld_dfs(legn_gyerek);

    for(int kov : graf[akt]){
        if(kov == legn_gyerek) continue;
        hld_fej[kov] = kov;
        hld_dfs(kov);
    }
}



struct seg_tree{
    int n;
    vector<int> ert;
    vector<int> alap;

    void init(vector<int> &_alap){
        alap = _alap;
        n = 1;
        while(n < alap.size()) n *= 2;
        ert.assign(2*n, -1);
        felepit(1, 0, n-1);
    }

    void felepit(int akt, int bal, int jobb){
        if(bal == jobb){
            if(bal < alap.size()){
                ert[akt] = alap[bal];
            }
            else{
                ert[akt] = -1;
            }
            return;
        }
        int kozep = (bal + jobb) / 2;
        felepit(akt*2, bal, kozep);
        felepit(akt*2+1, kozep+1, jobb);
        ert[akt] = max(ert[akt*2], ert[akt*2+1]);
    }

    int kerdez(int akt, int bal, int jobb, int xbal, int xjobb){
        if(jobb < xbal || xjobb < bal) return -1;
        if(xbal <= bal && jobb <= xjobb){
            return ert[akt];
        }

        int kozep = (bal + jobb) / 2;
        return max(kerdez(akt*2, bal, kozep, xbal, xjobb), kerdez(akt*2+1, kozep+1, jobb, xbal, xjobb));
    }

    int kerdez(int bal, int jobb){
        if(bal > jobb) swap(bal, jobb);
        return kerdez(1, 0, n-1, bal, jobb);
    }
};

void dfs(int akt, int mag=0, int sz=-1){
    meret[akt] = 1;
    magas[akt] = mag;
    szulo[akt] = sz;

    for(int kov : graf[akt]){
        dfs(kov, mag+1, akt);
        meret[akt] += meret[kov];
    }
}

int hely_to_ind(pii hely){
    return hely.first*m + hely.second;
}

struct feszitofa_struct{
    struct comp{
        bool operator()(const pii &a, const pii &b){
            return pont_ertek[hely_to_ind(a)] < pont_ertek[hely_to_ind(b)];
        }
    };

    int fej[MAXN];
    int meret[MAXN];
    vector<vector<int>> ideigl_graf;

    void unio(int a, int b){
        if(holvan(a) == holvan(b)) return;
        if(meret[a] > meret[b]) swap(a, b);

        fej[fej[a]] = fej[b];
    }

    int holvan(int a){
        if(a == fej[a]) return a;
        return fej[a] = holvan(fej[a]);
    }

    void beallit_dfs(int akt, int par=-1){
        for(int kov : ideigl_graf[akt]){
            if(kov == par) continue;
            graf[akt].push_back(kov);
            beallit_dfs(kov, akt);
        }
    }

    void keres_feszitot(){
        ideigl_graf.assign(n*m, vector<int>());
        for(int i = 0; i < n*m; i++){
            fej[i] = i;
            meret[i] = 1;
        }
        vector<pii> pontok;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                pontok.push_back({i, j});
            }
        }
        sort(pontok.begin(), pontok.end(), comp());

        for(auto p : pontok){
            int ind1 = hely_to_ind(p);
            for(int i = 0; i < 4; i++){
                pii kov = {p.first + valt_x[i], p.second + valt_y[i]};
                if(kov.first < 0 || kov.second < 0 || kov.first >= n || kov.second >= m) continue;
                int ind2 = hely_to_ind(kov);
                if(pont_ertek[ind2] > pont_ertek[ind1]) continue;


                int hely1=holvan(ind1), hely2=holvan(ind2);

                if(hely1 != hely2){
                    ideigl_graf[ind1].push_back(ind2);
                    ideigl_graf[ind2].push_back(ind1);
                    unio(ind1, ind2);
                }
            }
        }

        beallit_dfs(0);
    }
};

feszitofa_struct fs;
lca_struct ls;
seg_tree st;

int hld_kerdez(int a, int b){
    if(magas[a] < magas[b]) swap(a, b);

    int ret = -1;
    while(hld_fej[a] != hld_fej[b]){
        ret = max(ret, st.kerdez(hld_euler_ind[a], hld_euler_ind[hld_fej[a]]));
        a = szulo[hld_fej[a]];
    }

    ret = max(ret, st.kerdez(hld_euler_ind[a], hld_euler_ind[b]));

    return ret;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m >> q;

    for(int i = 0; i < n*m; i++){
        cin >> pont_ertek[i];
    }
    fs.keres_feszitot();

    dfs(0);

    hld_fej[0] = 0;
    hld_dfs(0);

    ls.build();
    st.init(hld_euler_ertek);

    int a1, a2, b1, b2, a, b;
    while(q--){
        cin >> a1 >> a2 >> b1 >> b2;
        a1--;
        a2--;
        b1--;
        b2--;
        a = hely_to_ind({a1, a2});
        b = hely_to_ind({b1, b2});

        int lca_ind = ls.lca(a, b);
        int ag1 = hld_kerdez(a, lca_ind);
        int ag2 = hld_kerdez(b, lca_ind);

        cout << max(ag1, ag2) << "\n";
    }

}
Részfeladat Összpont Teszt Verdikt Idő Memória
subtask1 0/0
1 Elfogadva 10ms 25620 KiB
2 Elfogadva 14ms 25972 KiB
subtask2 19/19
3 Elfogadva 18ms 29328 KiB
4 Elfogadva 18ms 28436 KiB
5 Elfogadva 18ms 28392 KiB
6 Elfogadva 18ms 28276 KiB
7 Elfogadva 17ms 28408 KiB
8 Elfogadva 18ms 28432 KiB
9 Elfogadva 18ms 28924 KiB
10 Elfogadva 17ms 29712 KiB
subtask3 20/20
11 Elfogadva 14ms 26976 KiB
12 Elfogadva 14ms 27460 KiB
13 Elfogadva 32ms 32604 KiB
14 Elfogadva 263ms 85472 KiB
15 Elfogadva 1.133s 316800 KiB
subtask4 20/20
16 Elfogadva 1.036s 317000 KiB
17 Elfogadva 1.304s 317152 KiB
18 Elfogadva 1.623s 242080 KiB
19 Elfogadva 1.694s 230568 KiB
20 Elfogadva 1.731s 229088 KiB
subtask5 31/31
21 Elfogadva 423ms 86676 KiB
22 Elfogadva 597ms 71928 KiB
23 Elfogadva 666ms 69408 KiB
24 Elfogadva 691ms 69524 KiB
25 Elfogadva 453ms 87184 KiB
26 Elfogadva 666ms 69344 KiB
27 Elfogadva 592ms 70448 KiB
28 Elfogadva 400ms 87136 KiB
29 Elfogadva 377ms 87168 KiB
subtask6 0/10
30 Elfogadva 2.302s 318292 KiB
31 Elfogadva 2.878s 242816 KiB
32 Elfogadva 2.654s 231180 KiB
33 Időlimit túllépés 3.078s 116748 KiB
34 Elfogadva 1.898s 318344 KiB
35 Elfogadva 2.223s 278532 KiB
36 Elfogadva 2.312s 227548 KiB
37 Elfogadva 2.372s 231108 KiB
38 Elfogadva 1.671s 318344 KiB
39 Elfogadva 1.414s 318344 KiB