5259 2023. 04. 24 12:36:44 sztomi Hegyi levegő cpp11 Elfogadva 100/100 2.927s 318408 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];
int folott[MAXN][MAXK];

void lca_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;

    void init(){
        n = 1;
        while(n < hld_euler_ertek.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 < hld_euler_ertek.size()){
                ert[akt] = hld_euler_ertek[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 comp{
    bool operator()(const pii &a, const pii &b){
        return pont_ertek[hely_to_ind(a)] < pont_ertek[hely_to_ind(b)];
    }
};

int unio_fej[MAXN];
int unio_meret[MAXN];
vector<int> ideigl_graf[MAXN];

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

    unio_fej[unio_fej[a]] = unio_fej[b];
}

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(){
    for(int i = 0; i < n*m; i++){
        unio_fej[i] = i;
        unio_meret[i] = 1;
    }
    vector<pii> pontok(n*m);
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            pontok[hely_to_ind({i, j})] = {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);
}

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];
    }
    keres_feszitot();

    dfs(0);

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

    lca_build();
    st.init();

    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 = lca(a, b);
        cout << max(hld_kerdez(a, lca_ind), hld_kerdez(b, lca_ind)) << "\n";
    }

}
Részfeladat Összpont Teszt Verdikt Idő Memória
subtask1 0/0
1 Elfogadva 25ms 48920 KiB
2 Elfogadva 24ms 49432 KiB
subtask2 19/19
3 Elfogadva 26ms 52540 KiB
4 Elfogadva 28ms 52020 KiB
5 Elfogadva 29ms 52168 KiB
6 Elfogadva 29ms 51912 KiB
7 Elfogadva 29ms 51784 KiB
8 Elfogadva 26ms 51844 KiB
9 Elfogadva 25ms 52140 KiB
10 Elfogadva 28ms 52808 KiB
subtask3 20/20
11 Elfogadva 24ms 50088 KiB
12 Elfogadva 26ms 50972 KiB
13 Elfogadva 41ms 56384 KiB
14 Elfogadva 289ms 104832 KiB
15 Elfogadva 1.129s 317340 KiB
subtask4 20/20
16 Elfogadva 1.307s 317188 KiB
17 Elfogadva 1.307s 317392 KiB
18 Elfogadva 1.348s 242064 KiB
19 Elfogadva 1.532s 230716 KiB
20 Elfogadva 1.47s 228952 KiB
subtask5 31/31
21 Elfogadva 453ms 105180 KiB
22 Elfogadva 591ms 90184 KiB
23 Elfogadva 707ms 88136 KiB
24 Elfogadva 686ms 88056 KiB
25 Elfogadva 435ms 105540 KiB
26 Elfogadva 648ms 87904 KiB
27 Elfogadva 596ms 88824 KiB
28 Elfogadva 412ms 105604 KiB
29 Elfogadva 382ms 105540 KiB
subtask6 10/10
30 Elfogadva 2.325s 318080 KiB
31 Elfogadva 2.927s 242560 KiB
32 Elfogadva 2.651s 230988 KiB
33 Elfogadva 2.746s 229316 KiB
34 Elfogadva 2.086s 318236 KiB
35 Elfogadva 2.138s 278248 KiB
36 Elfogadva 2.332s 227732 KiB
37 Elfogadva 2.206s 231528 KiB
38 Elfogadva 1.664s 318408 KiB
39 Elfogadva 1.587s 318392 KiB