Submission #1340560

#TimeUsernameProblemLanguageResultExecution timeMemory
1340560vladiliusBitaro's Travel 2 (JOI25_travel2)C++20
100 / 100
1609 ms129172 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define pb push_back
#define ff first
#define ss second
#define arr3 array<int, 3>

struct dsu{
    vector<vector<int>> tt, vv;
    vector<int> sz, p, pos;
    vector<pii> mx;
    int n, cc;
    dsu(int ns, vector<int> a){
        n = ns;
        sz.resize(n + 1);
        p.resize(n + 1);
        mx.resize(n + 1);
        for (int i = 1; i <= n; i++){
            sz[i] = 1;
            p[i] = i;
            mx[i] = {a[i], i};
        }
        pos.resize(n + 1);
        tt.resize(n + 1);
        vv.resize(n + 1);
        for (int i = 1; i <= n; i++){
            tt[i].pb(0);
            vv[i].pb(i);
        }
        cc = 0;
    }
    int get(int v){
        if (p[v] != v){
            return get(p[v]);
        }
        return v;
    }
    void unite(int x, int y){
        x = get(x); y = get(y);
        if (x == y) return;
        if (sz[x] > sz[y]) swap(x, y);
        tt[x].pb(cc);
        vv[x].pb(y);
        p[x] = y;
        sz[y] += sz[x];
        mx[y] = max(mx[y], mx[x]);
    }
    void nw(int v){
        pos[v] = ++cc;
    }
    vector<int> :: iterator it;
    int get(int x, int v){
        it = upper_bound(tt[v].begin(), tt[v].end(), x);
        int j = (int) (it - tt[v].begin()) - 1, p = vv[v][j];
        if (p != v){
            return get(x, p);
        }
        return v;
    }
    int f(int x, int y){
        return get(pos[x], x) == get(pos[x], y);
    }
};

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    
    int n, m, X; cin>>n>>m>>X;
    vector<vector<int>> a(n + 1, vector<int>(m + 1));
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= m; j++){
            cin>>a[i][j];
        }
    }
    
    const int N = n * m;

    vector<vector<int>> p(n + 1, vector<int>(m + 1));
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= m; j++){
            p[i][j] = (i - 1) * m + j;
        }
    }
    
    vector<int> adj[N + 1];
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= m; j++){
            if (i != 1) adj[p[i][j]].pb(p[i - 1][j]);
            if (j != 1) adj[p[i][j]].pb(p[i][j - 1]);
            if (i != n) adj[p[i][j]].pb(p[i + 1][j]);
            if (j != m) adj[p[i][j]].pb(p[i][j + 1]);
        }
    }

    vector<int> A(N + 1);
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= m; j++){
            A[p[i][j]] = a[i][j];
        }
    }
    
    vector<pii> all;
    for (int i = 1; i <= N; i++){
        all.pb({A[i], i});
    }
    sort(all.begin(), all.end());
    
    int j = 0;
    dsu T(N, A);
    vector<bool> act(N + 1);
    vector<int> P(N + 1);
    for (int i = 0; i < N; i++){
        T.nw(all[i].ss);
        while (j < N && all[j].ff <= (all[i].ff + X)){
            act[all[j].ss] = 1;
            for (int v: adj[all[j].ss]){
                if (act[v]){
                    T.unite(v, all[j].ss);
                }
            }
            j++;
        }
        P[all[i].ss] = T.mx[T.get(all[i].ss)].ss;
    }
    
    for (int i = 1; i <= N; i++){
        if (A[P[i]] == A[i]){
            P[i] = i;
        }
    }

    auto f = [&](int x, int y){
        return T.f(x, y);
    };
    
    const int lg = log2(N);
    vector<vector<int>> sp(N + 1, vector<int>(lg + 1));
    for (int i = 1; i <= N; i++) sp[i][0] = P[i];
    for (int j = 1; j <= lg; j++){
        for (int i = 1; i <= N; i++){
            sp[i][j] = sp[sp[i][j - 1]][j - 1];
        }
    }
    
    int q; cin>>q;
    while (q--){
        int x1, y1, x2, y2; cin>>x1>>y1>>x2>>y2;
        int a = p[x1][y1], b = p[x2][y2], cc = 1;
        if (f(a, b)){
            cout<<1<<"\n";
            continue;
        }
        for (int i = lg; i >= 0; i--){
            if (!f(sp[a][i], b)){
                a = sp[a][i];
                cc += (1 << i);
            }
        }

        if (f(P[a], b)){
            cout<<cc + 1<<"\n";
            continue;
        }
        cout<<-1<<"\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...