5254 2023. 04. 24 11:45:07 sztomi Hegyi levegő cpp17 Időlimit túllépés 90/100 3.085s 369228 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;
        }

        bool operator()(const pii &a, const pii &b){
            return ertek[a.first][a.second] < ertek[b.first][b.second];
        }
    };

    vector<int> fej;
    vector<vector<int>> ideigl_graf;

    void unio(int a, int b){
        if(holvan(a) == holvan(b)) return;
        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>());
        fej.resize(n*m);
        for(int i = 0; i < n*m; i++){
            fej[i] = i;
        }
        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){
            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;
                if(ertek[kov.first][kov.second] > ertek[p.first][p.second]) continue;


                int ind1 = hely_to_ind(p);
                int ind2 = hely_to_ind(kov);
                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;
    graf.assign(n*m, vector<int>());
    ertek.assign(n, vector<int>(m));
    pont_ertek.resize(n*m);

    //set<int> temp1;

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

    /*
    map<int, int> temp2;
    int temp3 = 0;
    for(int x : temp1){
        temp2[x] = temp3++;
    }
    cout <<"------------------\n";
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            ertek[i][j] = temp2[ertek[i][j]];
            pont_ertek[hely_to_ind({i, j})] = ertek[i][j];
            cout << ertek[i][j] << " ";
        }
        cout << "\n";
    }
    cout << "---------------------\n";
    */

    fs.keres_feszitot();
/*
    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 Összpont Teszt Verdikt Idő Memória
subtask1 0/0
1 Elfogadva 3ms 1960 KiB
2 Elfogadva 3ms 2312 KiB
subtask2 19/19
3 Elfogadva 8ms 5596 KiB
4 Elfogadva 8ms 5232 KiB
5 Elfogadva 8ms 5232 KiB
6 Elfogadva 8ms 5140 KiB
7 Elfogadva 8ms 5124 KiB
8 Elfogadva 8ms 5276 KiB
9 Elfogadva 8ms 5760 KiB
10 Elfogadva 8ms 7132 KiB
subtask3 20/20
11 Elfogadva 3ms 3600 KiB
12 Elfogadva 4ms 4192 KiB
13 Elfogadva 23ms 9996 KiB
14 Elfogadva 259ms 67044 KiB
15 Elfogadva 1.401s 317204 KiB
subtask4 20/20
16 Elfogadva 1.044s 317360 KiB
17 Elfogadva 1.49s 368208 KiB
18 Elfogadva 1.608s 242012 KiB
19 Elfogadva 1.736s 230452 KiB
20 Elfogadva 1.7s 229072 KiB
subtask5 31/31
21 Elfogadva 456ms 77632 KiB
22 Elfogadva 591ms 52424 KiB
23 Elfogadva 679ms 50192 KiB
24 Elfogadva 665ms 50396 KiB
25 Elfogadva 418ms 67876 KiB
26 Elfogadva 624ms 50296 KiB
27 Elfogadva 575ms 51436 KiB
28 Elfogadva 388ms 68212 KiB
29 Elfogadva 363ms 68220 KiB
subtask6 0/10
30 Elfogadva 2.588s 369228 KiB
31 Elfogadva 2.882s 242832 KiB
32 Elfogadva 2.648s 231136 KiB
33 Időlimit túllépés 3.085s 116544 KiB
34 Elfogadva 1.858s 318236 KiB
35 Elfogadva 2.114s 278332 KiB
36 Elfogadva 2.334s 226848 KiB
37 Elfogadva 2.201s 230348 KiB
38 Elfogadva 2.085s 318308 KiB
39 Elfogadva 1.667s 318240 KiB