52592023-04-24 12:36:44sztomiHegyi levegőcpp11Elfogadva 100/1002.927s318408 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ÖsszpontTesztVerdiktIdőMemória
subtask10/0
1Elfogadva25ms48920 KiB
2Elfogadva24ms49432 KiB
subtask219/19
3Elfogadva26ms52540 KiB
4Elfogadva28ms52020 KiB
5Elfogadva29ms52168 KiB
6Elfogadva29ms51912 KiB
7Elfogadva29ms51784 KiB
8Elfogadva26ms51844 KiB
9Elfogadva25ms52140 KiB
10Elfogadva28ms52808 KiB
subtask320/20
11Elfogadva24ms50088 KiB
12Elfogadva26ms50972 KiB
13Elfogadva41ms56384 KiB
14Elfogadva289ms104832 KiB
15Elfogadva1.129s317340 KiB
subtask420/20
16Elfogadva1.307s317188 KiB
17Elfogadva1.307s317392 KiB
18Elfogadva1.348s242064 KiB
19Elfogadva1.532s230716 KiB
20Elfogadva1.47s228952 KiB
subtask531/31
21Elfogadva453ms105180 KiB
22Elfogadva591ms90184 KiB
23Elfogadva707ms88136 KiB
24Elfogadva686ms88056 KiB
25Elfogadva435ms105540 KiB
26Elfogadva648ms87904 KiB
27Elfogadva596ms88824 KiB
28Elfogadva412ms105604 KiB
29Elfogadva382ms105540 KiB
subtask610/10
30Elfogadva2.325s318080 KiB
31Elfogadva2.927s242560 KiB
32Elfogadva2.651s230988 KiB
33Elfogadva2.746s229316 KiB
34Elfogadva2.086s318236 KiB
35Elfogadva2.138s278248 KiB
36Elfogadva2.332s227732 KiB
37Elfogadva2.206s231528 KiB
38Elfogadva1.664s318408 KiB
39Elfogadva1.587s318392 KiB