Submission #1363268

#TimeUsernameProblemLanguageResultExecution timeMemory
1363268nanaseyuzukiBitaro's Travel 2 (JOI25_travel2)C++20
100 / 100
1413 ms631664 KiB
#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pii pair<int, int>
#define all(a) a.begin(), a.end()
using namespace std;

#ifdef LOCAL
#include "C:\Users\Dell\Downloads\template\template\icpc-notebook\Utilities\debug.h"
#else
#define debug(...) 42
#endif

const int mn = 2e6 + 5, mod = 1e9 + 7, inf = 2e18;

int n, m, l, cnt;
vector <vector <int>> a;
vector <pii> mov = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

bool check(int x, int y) {
	return x >= 1 && x <= m && y >= 1 && y <= n;
}

int convert(int x, int y) {
	return n * (x - 1) + y;
}

int par_[mn], val[mn], d[mn], st[mn], ft[mn], euler[mn], timer_dfs = 0, up[mn][22], up_par[mn][22], lg2[mn], par[mn];
vector <int> adj[mn], nxt[mn];

void dfs(int u) {
	st[u] = ++ timer_dfs; euler[timer_dfs] = u;
	for(auto v : adj[u]) {
		d[v] = d[u] + 1;
		par[v] = u;
		dfs(v);
		euler[++ timer_dfs] = u;
	}
	ft[u] = timer_dfs;
}

int higher(int u, int v) {
	return (d[u] < d[v] ? u : v);
}

void build() {
	for(int i = 1; i <= timer_dfs; i++) up[i][0] = euler[i], up_par[i][0] = par[i];
	for(int j = 1; (1 << j) <= timer_dfs; j++) {
		for(int i = 1; i <= timer_dfs; i++) {
			up[i][j] = higher(up[i][j - 1], up[i + (1 << (j - 1))][j - 1]);
		}
	}
	for(int j = 1; j < 22; j++){
        for(int i = 1; i <= cnt; i++){
            up_par[i][j] = up_par[up_par[i][j - 1]][j - 1];
        }
    }
	lg2[0] = -1;
	for(int i = 1; i <= timer_dfs; i++) lg2[i] = lg2[i >> 1] + 1;
}

int lca(int u, int v) {
	int l = st[u], r = st[v];
	if(l > r) swap(l, r);
	int kc = lg2[r - l + 1];
	return higher(up[l][kc], up[r - (1 << kc) + 1][kc]);
}

int kc(int u, int v) {
	return val[lca(u, v)];
}

void init() {
	cnt = m * n;
	for(int i = 1; i <= m * n; i++) par_[i] = i;
}

int find(int u) {
	if(u == par_[u]) return u;
	return par_[u] = find(par_[u]);
}

void join(int u, int v, int w) {
	u = find(u), v = find(v);
	if(u == v) return;
	cnt ++;
	par_[u] = par_[v] = par_[cnt] = cnt;
	adj[cnt].push_back(u);
	adj[cnt].push_back(v);
	val[cnt] = w;
}

int jump(int u, int p){
    if(u == 0) return 0;
    if(val[u] >= p) return u;
    for(int j = 21; j >= 0; --j){
        int anc = up_par[u][j];
        if(anc != 0 && val[anc] <= p){
            u = anc;
        }
    }
    return u;
}

int st2[mn][22];

void dfs2(int u) {
	for(auto v : adj[u]) {
		st2[v][0] = jump(v, val[v] + l);
		dfs2(v);
	}
}

bool is_anc(int u, int v) {
	return st[u] <= st[v] && st[v] <= ft[u];
}

int ans[3005][3005];

void solve() {
    cin >> m >> n >> l;
    a.resize(m + 1, vector <int> (n + 1));

    for(int i = 1; i <= m; i++) {
    	for(int j = 1; j <= n; j++) {
    		cin >> a[i][j];
    		val[convert(i, j)] = a[i][j];
    	}
    }

    vector <array<int, 3>> edge;
    for(int i = 1; i <= m; i++) {
    	for(int j = 1; j <= n; j++) {
    		for(auto [di, dj] : mov) {
    			int ni = i + di, nj = j + dj;
    			if(check(ni, nj)) {
    				edge.push_back({max(a[i][j], a[ni][nj]), convert(i, j), convert(ni, nj)});
    			}
    		}
     	}
    }

    sort(all(edge));
    init();
    for(auto [w, u, v] : edge) join(u, v, w);
    dfs(cnt); build();
	  val[0] = 2e18;
	  dfs2(cnt);
    for(int j = 1; j < 22; j++){
        for(int i = 1; i <= cnt; i++){
            st2[i][j] = st2[st2[i][j - 1]][j - 1];
        }
    }

    int q; cin >> q;
    while(q--) {
        int x, y, u, v; cin >> x >> y >> u >> v;
        int a_ = convert(x, y), b_ = convert(u, v);

        if(a_ == b_) { cout << 0 << '\n'; continue; }

        int curr = jump(a_, val[a_] + l);
        if(is_anc(curr, b_)) {
            cout << 1 << '\n';
            continue;
        }

        int res = 1;

        for(int j = 21; j >= 0; j--) {
            int nxt = st2[curr][j];
            if (nxt != 0 && !is_anc(nxt, b_)) {
                curr = nxt;
                res += (1 << j);
            }
        }

        curr = st2[curr][0];
        res++;

        if(is_anc(curr, b_)){
            cout << res << '\n';
        }
        else cout << -1 << '\n';
    }
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    #define task "Kawabata"
    if (fopen(task".INP", "r")) {
        freopen(task".INP", "r", stdin);
        freopen(task".OUT", "w", stdout);
    }
    int t = 1;
    // cin >> t;
    while (t--) solve();
    return 0;
}
// Don't wanna lose anymore T_T
// Never let me go - Kazuo Ishiguro

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:194:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  194 |         freopen(task".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:195:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  195 |         freopen(task".OUT", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...