Submission #1349680

#TimeUsernameProblemLanguageResultExecution timeMemory
1349680vladmart09Railway Trip 2 (JOI22_ho_t4)C++20
0 / 100
465 ms120000 KiB
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <random>
#include <queue>
#include <numeric>
#include <array>
#include <iomanip>
#include <stack>
#include <chrono>
#include <climits>
#include <bitset>

using namespace std;

using ll = long long;
using ld = long double;
using vd = vector<ld>;
using vi = vector<ll>;
using vii = vector<vi>;
using viii = vector<vii>;
using pi = pair<ll, ll>;
using vpi = vector<pi>;
using vb = vector<bool>;
using vs = vector<string>;

#define vec vector
#define cmax(x, ...) x = max({x, __VA_ARGS__})
#define cmin(x, ...) x = min({x, __VA_ARGS__})
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

const ll N = 1e5 + 5, MOD = 1e9 + 7, INF = 1e18, K = 20;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct Seg {
	vi seg;
	ll n;
	bool mx;

	Seg(ll n_, vi arr, bool mx_) : n(n_), mx(mx_) {
		seg.assign(n * 2 + 1, (mx ? -INF : INF));

		for (ll i = 1; i <= n; i++) {
			seg[i + n] = arr[i];
		}

		for (ll i = n * 2; i > 1; i--) {
			if (mx) cmax(seg[i >> 1], seg[i]);
			else cmin(seg[i >> 1], seg[i]);
		}
	}

	ll get(ll l, ll r) {
		l += n, r += n;
		ll res = (mx ? -INF : INF);

		for (; l <= r; l >>= 1, r >>= 1) {
			if (l & 1) {
				if (mx) cmax(res, seg[l]);
				else cmin(res, seg[l]);
				l++;
			}
			if (~r & 1) {
				if (mx) cmax(res, seg[r]);
				else cmin(res, seg[r]);
				r--;
			}
		}

		return res;
	}

	void upd(ll i, ll v) {
		i += n;
		for (; i > 0; i >>= 1) {
			if (mx) cmax(seg[i], v);
			else cmin(seg[i], v);
		}
	}
};

void solve() {
	ll n, k, m; cin >> n >> k >> m;

	vii addR(n + 1), remR(n + 1);
	vii addL(n + 1), remL(n + 1);

	while (m--) {
		ll l, r; cin >> l >> r;

		if (l < r) {
			addR[l].push_back(r);
			remR[min(l + k - 1, r)].push_back(r);
		}
		else {
			addL[l].push_back(r);
			remL[max(r, l - k + 1)].push_back(r);
		}
	}

	vi left(n + 1), right(n + 1);

	multiset<ll> st;

	for (ll i = 1; i <= n; i++) {
		for (auto& x : addR[i]) {
			st.insert(x);
		}

		if (st.empty()) right[i] = i;
		else right[i] = *st.rbegin();

		for (auto& x : remR[i]) {
			st.erase(st.find(x));
		}
	}

	for (ll i = n; i >= 1; i--) {
		for (auto& x : addL[i]) {
			st.insert(x);
		}

		if (st.empty()) left[i] = i;
		else left[i] = *st.begin();

		for (auto& x : remL[i]) {
			st.erase(st.find(x));
		}
	}

	vector<Seg> segL(K, Seg(n, left, false));
	vector<Seg> segR(K, Seg(n, right, true));

	vii upR(n + 1, vi(K));
	vii upL(n + 1, vi(K));

	for (ll i = 1; i <= n; i++) {
		upL[i][0] = left[i];
		segL[0].upd(i, upL[i][0]);

		upR[i][0] = right[i];
		segR[0].upd(i, upR[i][0]);
	}

	for (ll j = 1; j < K; j++) {
		for (ll i = 1; i <= n; i++) {
			upL[i][j] = segL[j].get(upL[i][j - 1], upR[i][j - 1]);
			segL[j].upd(i, upL[i][j]);

			upR[i][j] = segR[j].get(upL[i][j - 1], upR[i][j - 1]);
			segR[j].upd(i, upR[i][j]);
		}
	}

	ll q; cin >> q;

	while (q--) {
		ll l, r; cin >> l >> r;

		if (l == r) {
			cout << '0' << '\n'; continue;
		}

		if (l <= r) {
			ll ans = 0;
			ll fin = -1;
			ll curL = l;
			ll curR = l;

			for (ll j = K - 1; j >= 0; j--) {
				ll res = segR[j].get(curL, curR);

				if (res < r) {
					curR = res; curL = segL[j].get(curL, curR);
					ans += (1ll << j);
				}
				else {
					fin = ans + (1ll << j);
				}
			}

			cout << fin << '\n';
		}
		else {
			ll ans = 0;
			ll fin = -1;
			ll curL = l;
			ll curR = l;

			for (ll j = K - 1; j >= 0; j--) {
				ll res = segL[j].get(curL, curR);

				if (res > r) {
					curL = res; curR = segR[j].get(curL, curR);
					ans += (1ll << j);
				}
				else {
					fin = ans + (1ll << j);
				}
			}

			cout << fin << '\n';
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	long long tt = 1;
	//cin >> tt;

	while (tt--) {
		solve();
		cout << '\n';
	}

	return 0;
}

/*


Можно начинать от 0 а также городов которые обнуляют. А вот что делать с делением хзшка




































Какие темы повторить:
1) мст
2) 2сат
3) точки артикуляции
4) ксор базис
5) эйлеровый цикл, путь
6) кмп
7) конвекс хулл
8) вафельное дерево
9) суфиксный массив
10) суффиксный автомат
11) ним

*/
#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...