Submission #1335987

#TimeUsernameProblemLanguageResultExecution timeMemory
1335987MateiKing80Bitaro's Travel 2 (JOI25_travel2)C++20
100 / 100
1875 ms69136 KiB
#include <bits/stdc++.h>

using namespace std;

const int N = 300005;
vector<int> vec[N];
int n, m, l;
int w[N], lift[20][N];

struct DSU {
	int papa[N], mx[N], sz[N];
	void init() {
		for (int i = 0; i < n; i ++) {
			papa[i] = i;
			mx[i] = i;
			sz[i] = 1;
		}
	}
	int real(int x) {
		if (papa[x] == x)
			return x;
		return papa[x] = real(papa[x]);
	}
	void join(int x, int y) {
		x = real(x);
		y = real(y);
		if (x == y) {
			return;
		}
		if (sz[x] > sz[y]) {
			swap(x, y);
		}
		if (w[mx[x]] > w[mx[y]]) {
			mx[y] = mx[x];
		}
		papa[x] = y;
		sz[y] += sz[x];
	}
	bool same_component(int x, int y) {
		return real(x) == real(y);
	}
	int find_max(int x) {
		return mx[real(x)];
	}
};

int lol (int _l, int c) {
	return m * _l + c;
}

struct Qry {
	int time, x, y, i;
	bool operator < (const Qry &oth) const {
		return time < oth.time;
	}
};

signed main() {
	cin >> n >> m >> l;
	//int _n = n, _m = m;
	for (int i = 0; i < n; i ++) {
		for (int j = 0; j < m; j ++) {
			int x;
			cin >> x;
			w[lol(i, j)] = x;
		}
	}
	for (int i = 0; i < n; i ++) {
		for (int j = 1; j < m; j ++) {
			vec[lol(i, j)].push_back(lol(i, j - 1));
			vec[lol(i, j - 1)].push_back(lol(i, j));
		}
	}
	for (int i = 1; i < n; i ++) {
		for (int j = 0; j < m; j ++) {
			vec[lol(i, j)].push_back(lol(i - 1, j));
			vec[lol(i - 1, j)].push_back(lol(i, j));
		}
	}
	n = n * m;
	DSU ds;
	ds.init();
	vector<int> srt(n);
	for (int i = 0; i < n; i ++) {
		srt[i] = i;
	}
	sort(srt.begin(), srt.end(), [&] (int x, int y) { return w[x] < w[y]; });
	int p = 0;
	for (auto i : srt) {
		while (p < (int)srt.size() && w[srt[p]] <= w[i] + l) {
			for (auto j : vec[srt[p]]) {
				if (w[srt[p]] >= w[j]) {
					ds.join(srt[p], j);
				}
			}
			p ++;
		}
		lift[0][i] = ds.find_max(i);
	}
	for (int i = 1; i < 20; i ++) {
		for (int j = 0; j < n; j ++) {
			lift[i][j] = lift[i - 1][lift[i - 1][j]];
		}
	}
	int q;
	cin >> q;
	vector<Qry> queries;
	while (q --) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		queries.push_back({0, lol(a - 1, b - 1), lol(c - 1, d - 1), (int)queries.size()});
	}
	for (int bit = 19; bit >= 0; bit --) {
		vector<Qry> new_qry;
		DSU ds_qry;
		ds_qry.init();
		for (auto i : queries) {
			new_qry.push_back({w[lift[bit][i.x]] + l, lift[bit][i.x], i.y, i.i});
		}
		p = 0;
		sort(new_qry.begin(), new_qry.end());
		for (auto i : new_qry) {
			while (p < (int)srt.size() && w[srt[p]] <= i.time) {
				for (auto j : vec[srt[p]]) {
					if (w[srt[p]] >= w[j]) {
						ds_qry.join(srt[p], j);
					}
				}
				p ++;
			}
			if (!ds_qry.same_component(i.x, i.y)) {
				queries[i.i].time += (1 << bit);
				queries[i.i].x = lift[bit][queries[i.i].x];
			}
		}
	}
	vector<Qry> new_qry;
	ds.init();
	for (auto i : queries) {
		new_qry.push_back({w[i.x] + l, i.x, i.y, i.i});
	}
	p = 0;
	sort(new_qry.begin(), new_qry.end());
	for (auto i : new_qry) {
		while (p < (int)srt.size() && w[srt[p]] <= i.time) {
			for (auto j : vec[srt[p]]) {
				if (w[srt[p]] >= w[j]) {
					ds.join(srt[p], j);
				}
			}
			p ++;
		}
		if (ds.same_component(i.x, i.y)) {
			queries[i.i].time = -1;
		}
	}
	
	for (auto i : queries) {
		if (i.time == (1 << 20) - 1) {
			cout << -1 << '\n';
		} else {
			cout << i.time + 2 << '\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...