52572023-04-24 12:27:26sztomiHegyi levegőcpp11Hibás válasz 20/1003.101s650544 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ÖsszpontTesztVerdiktIdőMemória
subtask10/0
1Elfogadva12ms25368 KiB
2Hibás válasz10ms25844 KiB
subtask20/19
3Elfogadva17ms31284 KiB
4Időlimit túllépés3.101s15852 KiB
5Időlimit túllépés3.065s15952 KiB
6Időlimit túllépés3.076s15992 KiB
7Időlimit túllépés3.082s16280 KiB
8Időlimit túllépés3.069s16484 KiB
9Időlimit túllépés3.062s16764 KiB
10Elfogadva20ms32452 KiB
subtask320/20
11Elfogadva13ms27360 KiB
12Elfogadva14ms28292 KiB
13Elfogadva37ms38112 KiB
14Elfogadva375ms145772 KiB
15Elfogadva1.444s649560 KiB
subtask40/20
16Elfogadva1.723s649624 KiB
17Elfogadva1.71s649764 KiB
18Időlimit túllépés3.089s288776 KiB
19Időlimit túllépés3.078s283080 KiB
20Időlimit túllépés3.085s282396 KiB
subtask50/31
21Elfogadva444ms146508 KiB
22Időlimit túllépés3.073s67192 KiB
23Időlimit túllépés3.092s66020 KiB
24Időlimit túllépés3.082s65996 KiB
25Elfogadva446ms146480 KiB
26Időlimit túllépés3.068s66020 KiB
27Időlimit túllépés3.069s66288 KiB
28Elfogadva409ms146664 KiB
29Elfogadva398ms146672 KiB
subtask60/10
30Elfogadva1.955s650236 KiB
31Időlimit túllépés3.094s288992 KiB
32Időlimit túllépés3.079s283360 KiB
33Időlimit túllépés3.081s282740 KiB
34Elfogadva2.604s650472 KiB
35Időlimit túllépés3.101s307160 KiB
36Időlimit túllépés3.069s278292 KiB
37Időlimit túllépés3.096s279960 KiB
38Elfogadva2.269s650484 KiB
39Elfogadva1.621s650544 KiB