Submission #1203890

#TimeUsernameProblemLanguageResultExecution timeMemory
1203890TriseedotRailway Trip 2 (JOI22_ho_t4)C++20
100 / 100
1540 ms76280 KiB
// Made by ordinary newbie #pragma region setup #include <bits/stdc++.h> #include <random> #include <chrono> using namespace std; // variables //#define int long long using ld = long double; using ll = long long; using ull = unsigned long long; template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>; // bitwise operations #define cnt_bit(n) __builtin_popcountll(n) #define low_bit(n) ((n) & (-(n))) #define bit(n, i) (((n) >> (i)) & 1) #define set_bit(n, i) ((n) | (1ll << (i))) #define reset_bit(n, i) ((n) & ~(1ll << (i))) #define flip_bit(n, i) ((n) ^ (1ll << (i))) // math #define sqr(n) ((n) * (n)) int log2_floor(ull n) { return n ? __builtin_clzll(1) - __builtin_clzll(n) : -1; } const ll INF = 1e18; // utils #define len(x) (int) x.size() #define all(a) a.begin(), a.end() #define rall(a) a.rbegin(), a.rend() template <typename T> istream& operator>>(istream& is, vector<T>& v) { for(auto& el : v) { is >> el; } return is; } template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) { for (int i = 0; i < len(v); i++) { if (i) os << ' '; os << v[i]; } return os; } template<class... Args> auto create(size_t n, Args&&... args) { if constexpr(sizeof...(args) == 1) { return vector(n, args...); } else { return vector(n, create(args...)); } } struct custom_hash { static uint64_t splitmix64(uint64_t x) { x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); } size_t operator()(pair<int, int> x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x.first + FIXED_RANDOM) ^ splitmix64(x.second + FIXED_RANDOM); } }; template<typename T, typename U> bool chmin(T& a, const U b) { if (b < a) { a = b; return true; } return false; } template<typename T, typename U> bool chmax(T& a, const U b) { if (b > a) { a = b; return true; } return false; } template<typename T> void compress(vector<T>& v) { int n = len(v); vector<pair<T, int>> u(n); for (int i = 0; i < n; i++) { u[i] = {v[i], i}; } sort(all(u)); int curr = 0; for (int i = 0; i < n; i++) { if (i != 0 && u[i].first != u[i - 1].first) curr++; v[u[i].second] = curr; } } mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); #pragma endregion struct SegmentTreeMin { typedef int value; typedef int update; const value NEUTRAL_VALUE = 1e9; value combine_value(value a, value b) { return min(a, b); } value apply_update(value a, update b) { return b; } int n; vector<value> tree; SegmentTreeMin(int N) { n = N; tree.assign(4 * n, NEUTRAL_VALUE); } void build(int v, int l, int r, vector<value>& a) { if (l + 1 == r) { tree[v] = a[l]; return; } int m = (l + r) / 2; build(2 * v, l, m, a); build(2 * v + 1, m, r, a); tree[v] = combine_value(tree[2 * v], tree[2 * v + 1]); } SegmentTreeMin(vector<value> a) { n = len(a); tree.assign(4 * n, NEUTRAL_VALUE); build(1, 0, n, a); } void modify(int v, int l, int r, int qi, update u) { if (r <= qi || qi < l) { return; } if (l + 1 == r) { tree[v] = apply_update(tree[v], u); return; } int m = (l + r) / 2; modify(2 * v, l, m, qi, u); modify(2 * v + 1, m, r, qi, u); tree[v] = combine_value(tree[2 * v], tree[2 * v + 1]); } void modify(int qi, update u) { modify(1, 0, n, qi, u); } value get(int v, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) { return tree[v]; } if (r <= ql || qr <= l) { return NEUTRAL_VALUE; } int m = (l + r) / 2; return combine_value(get(2 * v, l, m, ql, qr), get(2 * v + 1, m, r, ql, qr)); } value get(int ql, int qr) { return get(1, 0, n, ql, qr); } }; struct SegmentTreeMax { typedef int value; typedef int update; const value NEUTRAL_VALUE = 0; value combine_value(value a, value b) { return max(a, b); } value apply_update(value a, update b) { return b; } int n; vector<value> tree; SegmentTreeMax(int N) { n = N; tree.assign(4 * n, NEUTRAL_VALUE); } void build(int v, int l, int r, vector<value>& a) { if (l + 1 == r) { tree[v] = a[l]; return; } int m = (l + r) / 2; build(2 * v, l, m, a); build(2 * v + 1, m, r, a); tree[v] = combine_value(tree[2 * v], tree[2 * v + 1]); } SegmentTreeMax(vector<value> a) { n = len(a); tree.assign(4 * n, NEUTRAL_VALUE); build(1, 0, n, a); } void modify(int v, int l, int r, int qi, update u) { if (r <= qi || qi < l) { return; } if (l + 1 == r) { tree[v] = apply_update(tree[v], u); return; } int m = (l + r) / 2; modify(2 * v, l, m, qi, u); modify(2 * v + 1, m, r, qi, u); tree[v] = combine_value(tree[2 * v], tree[2 * v + 1]); } void modify(int qi, update u) { modify(1, 0, n, qi, u); } value get(int v, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) { return tree[v]; } if (r <= ql || qr <= l) { return NEUTRAL_VALUE; } int m = (l + r) / 2; return combine_value(get(2 * v, l, m, ql, qr), get(2 * v + 1, m, r, ql, qr)); } value get(int ql, int qr) { return get(1, 0, n, ql, qr); } }; const int L = 20; void solve() { int n, k; cin >> n >> k; vector<SegmentTreeMin> binup_l(L, SegmentTreeMin(n)); vector<SegmentTreeMax> binup_r(L, SegmentTreeMax(n)); int qn; cin >> qn; vector<vector<pair<int, int>>> events(n + 1); for (int i = 0; i < qn; i++) { int a, b; cin >> a >> b; if (a < b) { a--; events[a].push_back({0, b}); events[min(a + k, b)].push_back({1, b}); } else { swap(a, b); a--; events[b].push_back({3, a}); events[max(a, b - k)].push_back({2, a}); } } multiset<int> curr_l, curr_r; for (int i = 0; i < n; i++) { for (auto [x, val] : events[i]) { if (x == 0) { curr_r.insert(val); } if (x == 1) { curr_r.erase(curr_r.find(val)); } if (x == 2) { curr_l.insert(val); } if (x == 3) { curr_l.erase(curr_l.find(val)); } } if (curr_l.empty()) { binup_l[0].modify(i, i); } else { binup_l[0].modify(i, *curr_l.begin()); } if (curr_r.empty()) { binup_r[0].modify(i, i + 1); } else { binup_r[0].modify(i, *prev(curr_r.end())); } } for (int i = 1; i < L; i++) { for (int j = 0; j < n; j++) { int l = binup_l[i - 1].get(binup_l[i - 1].get(j, j + 1), binup_r[i - 1].get(j, j + 1)); int r = binup_r[i - 1].get(binup_l[i - 1].get(j, j + 1), binup_r[i - 1].get(j, j + 1)); binup_l[i].modify(j, l); binup_r[i].modify(j, r); } } int h; cin >> h; while (h--) { int x, y; cin >> x >> y; x--, y--; int l = x, r = x + 1, ans = 0; for (int i = L - 1; i >= 0; i--) { int l1 = binup_l[i].get(l, r); int r1 = binup_r[i].get(l, r); if (l1 <= y && y < r1) continue; ans += 1 << i; l = l1; r = r1; } if (ans > n) { cout << -1 << '\n'; } else { cout << ans + 1 << '\n'; } } } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int tt = 1; //cin >> tt; for (int i = 1; i <= tt; i++) { solve(); } }
#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...