// 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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |