Submission #1347448

#TimeUsernameProblemLanguageResultExecution timeMemory
1347448hminhatBitaro's Travel 2 (JOI25_travel2)C++17
100 / 100
1949 ms382976 KiB
/*	
	ROAD TO TST 
*/
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define fi first
#define se second
#define pii pair<int, int>
#define el "\n"
#define pb push_back
#define all(v) v.begin(), v.end()

#define rep(i, x, y) for(int i = x, _y = y; i <= _y; i++)
#define rev(i, x, y) for(int i = x, _y = y; i >= _y; i--)

void file() {
	#define name "test"
	if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin);freopen(name".out", "w", stdout);}
	else {
		#undef name
		#define name "C:\\Users\\hminh\\Desktop\\2026\\AIO\\test"
		if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin);freopen(name".out", "w", stdout);}
	}
}

const int nmax = 6e5 + 7;

int n, m, q, L;
vector<vector<int>> a, nx[19];
int dx[] = {0, 0, -1, 1}, dy[] = {1, -1, 0, 0};
int par[nmax], maxx[nmax], val[nmax], up[19][nmax], h[nmax];
vector<int> g[nmax]; 
struct edge {
	int u, v, w;
	edge(int _u = 0, int _v = 0, int _w = 0) {
		u = _u, v = _v, w = _w;
	}
};
bool cmp(edge a, edge b) {
	return a.w == b.w ? a.v > b.v : a.w < b.w;
}
vector<edge> E;

int find_par(int u) {
	return u == par[u] ? u : par[u] = find_par(par[u]);
}

void construct() {
	int cur = n * m - 1;
	rep(i, 0, 2 * n * m - 1) par[i] = i;
	for(edge e : E) {
		int u = e.u, v = e.v;
		u = find_par(u), v = find_par(v);
		if(u == v) continue;
		cur++;
		val[cur] = e.w;
		g[cur].pb(u), g[cur].pb(v);
		par[u] = par[v] = cur;
	}
}

void dfs(int u) {
	for(int v : g[u]) {
		up[0][v] = u;
		h[v] = h[u] + 1;
		rep(i, 1, 18) {
			if((1 << i) > h[v]) continue;
			up[i][v] = up[i - 1][up[i - 1][v]];
		}
		dfs(v);
	}
}

int lca(int u, int v) {
	if(h[u] < h[v]) swap(u, v);
	int k = h[u] - h[v];
	rev(i, 18, 0) {
		if(k >> i & 1) u = up[i][u];
	}
	if(u == v) return u;
	rev(i, 18, 0) {
		if(up[i][u] != up[i][v]) u = up[i][u], v = up[i][v];
	}
	return up[0][u];
}

void build_krt() {
	rep(i, 0, n - 1) {
		rep(j, 0, m - 1) {
			rep(p, 0, 3) {
				int x = i + dx[p], y = j + dy[p];
				if(x < 0 || y < 0 || x >= n || y >= m) continue;
				E.pb(edge(i * m + j, x * m + y, max(a[i][j], a[x][y])));
			}
		}
	}
	sort(all(E), cmp);
	construct();
	dfs(2 * n * m - 2);
}

int pos[nmax];

void union_sets(int u, int v) {
	u = find_par(u), v = find_par(v);
	if(u == v) return;
	par[v] = u;
	if(maxx[u] < maxx[v]) pos[u] = pos[v];
	maxx[u] = max(maxx[u], maxx[v]);
}

void build_next() {
	rep(k, 0, 18) {
		nx[k].resize(n);
		rep(i, 0, n - 1) nx[k][i].resize(m, 0);
	}
	rep(i, 0, n * m - 1) par[i] = i, maxx[i] = a[i / m][i % m], pos[i] = i;
	rep(i, 0, n - 1) {
		rep(j, 0, m - 1) {
			E.pb(edge(i * m + j, 1, a[i][j]));
			E.pb(edge(i * m + j, -1, a[i][j] + L));
		}
	}
	sort(all(E), cmp);
	for(edge e : E) {
		int id = e.u, t = e.v, w = e.w;
		int i = id / m, j = id % m;
		if(t == 1) {
			rep(p, 0, 3) {
				int x = i + dx[p], y = j + dy[p];
				if(x < 0 || y < 0 || x >= n || y >= m || a[x][y] > w) continue;
				union_sets(id, x * m + y);
				// cout << i << ' ' << j << ' ' << x << ' ' << y << el;
			}
		}
		else {
			int idx = pos[find_par(id)];
			nx[0][i][j] = idx;
		}
	}
	rep(k, 1, 18) rep(i, 0, n - 1) rep(j, 0, m - 1) {
		int id = nx[k - 1][i][j];
		nx[k][i][j] = nx[k - 1][id / m][id % m];
	} 
}

int main()
{
	file();
	ios_base::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin >> n >> m >> L;
	a.resize(n);
	rep(i, 0, n - 1) {
		a[i].resize(m);
		rep(j, 0, m - 1) cin >> a[i][j];
	}
	build_krt();
	E.clear();
	build_next();
	cin >> q;
	while(q -- ) {
		int x, y, u, v;
		cin >> x >> y >> u >> v;
		x--,y--,u--,v--;
		int h = val[lca(x * m + y, u * m + v)], res = 0;
		rev(k, 18, 0) {
			int id = nx[k][x][y], i = id / m, j = id % m;
			if(a[i][j] < h) {
				res += 1 << k;
				x = i, y = j;
			}
		}
		// cout << h << ' ' << res << ' ' << x << ' ' << y << ' ' << a[x][y] << el;
		if(a[x][y] >= h - L) cout << res + 1;
		else cout << -1;
		cout << el;
	}
	return 0;
}

Compilation message (stderr)

Main.cpp: In function 'void file()':
Main.cpp:21:44: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   21 |         if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin);freopen(name".out", "w", stdout);}
      |                                     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:21:76: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   21 |         if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin);freopen(name".out", "w", stdout);}
      |                                                                     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:25:52: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   25 |                 if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin);freopen(name".out", "w", stdout);}
      |                                             ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:25:84: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   25 |                 if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin);freopen(name".out", "w", stdout);}
      |                                                                             ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...