52572023-04-24 12:27:26sztomiHegyi levegőcpp11Wrong answer 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";
    }

}
SubtaskSumTestVerdictTimeMemory
subtask10/0
1Accepted12ms25368 KiB
2Wrong answer10ms25844 KiB
subtask20/19
3Accepted17ms31284 KiB
4Time limit exceeded3.101s15852 KiB
5Time limit exceeded3.065s15952 KiB
6Time limit exceeded3.076s15992 KiB
7Time limit exceeded3.082s16280 KiB
8Time limit exceeded3.069s16484 KiB
9Time limit exceeded3.062s16764 KiB
10Accepted20ms32452 KiB
subtask320/20
11Accepted13ms27360 KiB
12Accepted14ms28292 KiB
13Accepted37ms38112 KiB
14Accepted375ms145772 KiB
15Accepted1.444s649560 KiB
subtask40/20
16Accepted1.723s649624 KiB
17Accepted1.71s649764 KiB
18Time limit exceeded3.089s288776 KiB
19Time limit exceeded3.078s283080 KiB
20Time limit exceeded3.085s282396 KiB
subtask50/31
21Accepted444ms146508 KiB
22Time limit exceeded3.073s67192 KiB
23Time limit exceeded3.092s66020 KiB
24Time limit exceeded3.082s65996 KiB
25Accepted446ms146480 KiB
26Time limit exceeded3.068s66020 KiB
27Time limit exceeded3.069s66288 KiB
28Accepted409ms146664 KiB
29Accepted398ms146672 KiB
subtask60/10
30Accepted1.955s650236 KiB
31Time limit exceeded3.094s288992 KiB
32Time limit exceeded3.079s283360 KiB
33Time limit exceeded3.081s282740 KiB
34Accepted2.604s650472 KiB
35Time limit exceeded3.101s307160 KiB
36Time limit exceeded3.069s278292 KiB
37Time limit exceeded3.096s279960 KiB
38Accepted2.269s650484 KiB
39Accepted1.621s650544 KiB