5257 2023. 04. 24 12:27:26 sztomi Hegyi levegő cpp11 Hibás válasz 20/100 3.101s 650544 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{
    vector<vector<pii>> ertek;
    vector<int> log_floor;
    int euler_ind[MAXN];
    vector<int> euler;

    void dfs(int akt){
        euler_ind[akt] = euler.size();
        euler.push_back(akt);
        for(int kov : graf[akt]){
            dfs(kov);
            euler.push_back(akt);
        }
    }

    void build(){
        dfs(0);
        int nx = euler.size();

        log_floor.resize(nx+1);
        log_floor[1] = 0;
        for(int i = 2; i <= nx; i++){
            log_floor[i] = log_floor[i/2]+1;
        }

        ertek.assign(nx, vector<pii>(log_floor[nx]+1, {INF, -1}));
        for(int i = 0; i < nx; i++){
            ertek[i][0] = {magas[euler[i]], euler[i]};
        }


        for(int i = 1; i <= log_floor[nx]; i++){
            for(int j = 0; j + (1 << i) < nx; j++){
                ertek[j][i] = min(ertek[j][i-1], ertek[j+(1 << i)][i-1]);
            }
        }
        //cout << "buildkesz\n";
    }

    int lca(int a, int b){
        if(euler_ind[a] > euler_ind[b]) swap(a, b);
        int len = euler_ind[b] - euler_ind[a] + 1;
        int i = log_floor[len];
        pii ret = min(ertek[euler_ind[a]][i], ertek[euler_ind[b] - (1 << i) + 1][i]);
        /*
        cout << "---------------------------\n";
        cout << euler.size() << "\n";
        cout << ertek[euler_ind[a]][i].first << " " << ertek[euler_ind[b] - (1 << i) + 1][i].first << "\n";
        cout << "len: " << len << " i: " << i << "\n";
        cout << euler_ind[b] - (1 << i) + 1 << "\n";
        cout << euler_ind[a] << " " << euler_ind[b] << "\n";
        cout << "lca of " << a << " and " << b << " is {" << ret.first << ", " << ret.second << "}\n";
        cout << "---------------------------\n";
        */
        return ret.second;
    }
};

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 12ms 25368 KiB
2 Hibás válasz 10ms 25844 KiB
subtask2 0/19
3 Elfogadva 17ms 31284 KiB
4 Időlimit túllépés 3.101s 15852 KiB
5 Időlimit túllépés 3.065s 15952 KiB
6 Időlimit túllépés 3.076s 15992 KiB
7 Időlimit túllépés 3.082s 16280 KiB
8 Időlimit túllépés 3.069s 16484 KiB
9 Időlimit túllépés 3.062s 16764 KiB
10 Elfogadva 20ms 32452 KiB
subtask3 20/20
11 Elfogadva 13ms 27360 KiB
12 Elfogadva 14ms 28292 KiB
13 Elfogadva 37ms 38112 KiB
14 Elfogadva 375ms 145772 KiB
15 Elfogadva 1.444s 649560 KiB
subtask4 0/20
16 Elfogadva 1.723s 649624 KiB
17 Elfogadva 1.71s 649764 KiB
18 Időlimit túllépés 3.089s 288776 KiB
19 Időlimit túllépés 3.078s 283080 KiB
20 Időlimit túllépés 3.085s 282396 KiB
subtask5 0/31
21 Elfogadva 444ms 146508 KiB
22 Időlimit túllépés 3.073s 67192 KiB
23 Időlimit túllépés 3.092s 66020 KiB
24 Időlimit túllépés 3.082s 65996 KiB
25 Elfogadva 446ms 146480 KiB
26 Időlimit túllépés 3.068s 66020 KiB
27 Időlimit túllépés 3.069s 66288 KiB
28 Elfogadva 409ms 146664 KiB
29 Elfogadva 398ms 146672 KiB
subtask6 0/10
30 Elfogadva 1.955s 650236 KiB
31 Időlimit túllépés 3.094s 288992 KiB
32 Időlimit túllépés 3.079s 283360 KiB
33 Időlimit túllépés 3.081s 282740 KiB
34 Elfogadva 2.604s 650472 KiB
35 Időlimit túllépés 3.101s 307160 KiB
36 Időlimit túllépés 3.069s 278292 KiB
37 Időlimit túllépés 3.096s 279960 KiB
38 Elfogadva 2.269s 650484 KiB
39 Elfogadva 1.621s 650544 KiB