52502023-04-24 09:24:27sztomiHegyi levegőcpp17Hibás válasz 20/1002.721s372716 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;
vector<vector<int>> ertek;
vector<int> pont_ertek;

vector<vector<int>> graf;

vector<int> szulo;
vector<int> magas;
vector<int> meret;


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

    void build(){
        int n = szulo.size();
        for(int i = 0; i < n; 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 < n; 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];
    }
};

vector<int> hld_euler_ertek;
vector<int> hld_euler_ind;
vector<int> hld_fej;

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 adat{
        pii hely;
        int ertek;
        pii elozo;
    };


    struct comp{
        bool operator()(const adat &a, const adat &b){
            return a.ertek > b.ertek;
        }
    };


    void keres_feszitot(pii kezd){
        priority_queue<adat, vector<adat>, comp> pq;
        pq.push({kezd, ertek[kezd.first][kezd.second], {-1, -1}});
        vector<vector<int>> ut_ertek(n, vector<int>(m, INF));
        vector<vector<bool>> volt(n, vector<bool>(m, false));
        vector<vector<pii>> elozo(n, vector<pii>(m, {-1, -1}));

        while(!pq.empty()){
            adat akt = pq.top();
            pq.pop();

            if(volt[akt.hely.first][akt.hely.second]) continue;
            volt[akt.hely.first][akt.hely.second] = true;
            ut_ertek[akt.hely.first][akt.hely.second] = akt.ertek;
            //cout << "akt: (" << akt.hely.first << " " << akt.hely.second << ") " << akt.ertek << " (" << akt.elozo.first << " " << akt.elozo.second << ")\n";

            vector<pii> kovik;
            for(int i = 0; i < 4; i++){
                pii kov = {akt.hely.first + valt_x[i], akt.hely.second + valt_y[i]};
                if(kov.first < 0 || kov.second < 0 || kov.first >= n || kov.second >= m) continue;
                kovik.push_back(kov);
            }

            for(pii &kov : kovik){
                int uj_ertek = max(akt.ertek, ertek[kov.first][kov.second]);
                if(ut_ertek[kov.first][kov.second] > uj_ertek){
                    //cout << "elozo ertek allitasa " << kov.first << " " << kov.second << " ertek: " << akt.ertek << "\n";
                    ut_ertek[kov.first][kov.second] = uj_ertek;
                    pq.push({kov, ut_ertek[kov.first][kov.second], akt.hely});
                    elozo[kov.first][kov.second] = akt.hely;
                }
            }
        }


        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(elozo[i][j].first == -1) continue;
                graf[hely_to_ind(elozo[i][j])].push_back(hely_to_ind({i, j}));
            }
        }
    }
};

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;
    graf.assign(n*m, vector<int>());
    ertek.assign(n, vector<int>(m));
    pont_ertek.resize(n*m);

    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> ertek[i][j];
            pont_ertek[hely_to_ind({i, j})] = ertek[i][j];
        }
    }

    fs.keres_feszitot({0, 0});
/*
    for(int i = 0; i < n*m; i++){
        cout << i << ": ";
        for(int x : graf[i]){
            cout << x << ", ";
        }
        cout << "\n";
    }
*/
    magas.resize(n*m);
    szulo.resize(n*m);
    meret.resize(n*m);
    dfs(0);

    hld_euler_ind.resize(n*m);
    hld_fej.resize(n*m);
    hld_fej[0] = 0;
    hld_dfs(0);

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

/*
    cout << "------------------\n";
    for(int i = 0; i < n*m; i++){
        cout << i << ": " << hld_fej[i] << " " << hld_euler_ind[i] << "\n";
    }
    cout << "\n";
*/

    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});
        //cout << "a_hely: " << a << " b_hely: " << b << "\n";

        int lca_ind = ls.lca(a, b);
        //cout << "lca: " << lca_ind << "\n";
        int ag1 = hld_kerdez(a, lca_ind);
        //cout <<"---------\n";
        int ag2 = hld_kerdez(b, lca_ind);
        //cout << "ag1 " << ag1 << " ag2 " << ag2 << "\n";

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

}
RészfeladatÖsszpontTesztVerdiktIdőMemória
subtask10/0
1Elfogadva3ms1960 KiB
2Hibás válasz3ms2336 KiB
subtask20/19
3Elfogadva7ms5092 KiB
4Hibás válasz7ms4616 KiB
5Hibás válasz8ms4832 KiB
6Hibás válasz8ms5068 KiB
7Hibás válasz8ms5184 KiB
8Hibás válasz8ms5252 KiB
9Hibás válasz8ms5368 KiB
10Elfogadva8ms7580 KiB
subtask320/20
11Elfogadva3ms3512 KiB
12Elfogadva4ms4024 KiB
13Elfogadva19ms8952 KiB
14Elfogadva236ms55436 KiB
15Elfogadva973ms258736 KiB
subtask40/20
16Elfogadva783ms258788 KiB
17Elfogadva953ms367604 KiB
18Hibás válasz1.059s177364 KiB
19Hibás válasz1.353s169972 KiB
20Hibás válasz1.264s169292 KiB
subtask50/31
21Elfogadva435ms77264 KiB
22Hibás válasz572ms40092 KiB
23Hibás válasz666ms38344 KiB
24Hibás válasz686ms38560 KiB
25Elfogadva513ms56472 KiB
26Hibás válasz674ms38732 KiB
27Hibás válasz614ms38920 KiB
28Elfogadva377ms56576 KiB
29Hibás válasz472ms45788 KiB
subtask60/10
30Elfogadva1.703s372716 KiB
31Hibás válasz2.065s187660 KiB
32Hibás válasz2.404s185508 KiB
33Hibás válasz2.721s189232 KiB
34Elfogadva1.523s279324 KiB
35Hibás válasz1.766s229604 KiB
36Hibás válasz2.321s193104 KiB
37Hibás válasz2.187s196000 KiB
38Elfogadva1.812s289640 KiB
39Hibás válasz2.282s234924 KiB