This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// Hallelujah, praise the one who set me free
// Hallelujah, death has lost its grip on me
// You have broken every chain, There's salvation in your name
// Jesus Christ, my living hope
#include <bits/stdc++.h>
using namespace std;
#define REP(i, s, e) for (int i = (s); i < (e); i++)
#define RREP(i, s, e) for (int i = (s); i >= (e); i--)
template <class T>
inline bool mnto(T& a, T b) {return a > b ? a = b, 1 : 0;}
template <class T>
inline bool mxto(T& a, T b) {return a < b ? a = b, 1: 0;}
typedef long long ll;
typedef long double ld;
#define FI first
#define SE second
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef tuple<int, int, int> iii;
#define ALL(_a) _a.begin(), _a.end()
#define SZ(_a) (int) _a.size()
#define pb push_back
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<ii> vii;
typedef vector<iii> viii;
#ifndef DEBUG
#define cerr if (0) cerr
#endif
const int INF = 1000000005;
const ll LINF = 1000000000000000005ll;
const int MAXN = 100005;
const int MAXM = 200005;
const int MAXL = 20;
int n, k, m;
ii ab[MAXM];
ii p[MAXL][MAXM];
ii src[MAXN];
int q;
ii fw[MAXN];
void upd(int i, ii x) {
for (; i <= n; i += i & -i) {
mxto(fw[i], x);
}
}
ii qmx(int i) {
ii res = {-INF, -INF};
for (; i > 0; i -= i & -i) {
mxto(res, fw[i]);
}
return res;
}
namespace DSU {
int rt[MAXN], p[MAXN], rnk[MAXN];
void init() {
REP (i, 1, n + 2) {
p[i] = i;
rt[i] = i;
rnk[i] = 1;
}
}
int findp(int i) {
if (p[i] == i) {
return i;
}
return p[i] = findp(p[i]);
}
bool join(int a, int b) {
int pa = findp(a), pb = findp(b);
if (pa == pb) {
return 0;
}
if (rnk[pa] < rnk[pb]) {
swap(pa, pb);
} else if (rnk[pa] == rnk[pb]) {
rnk[pa]++;
}
p[pb] = pa;
mxto(rt[pa], rt[pb]);
return 1;
}
}
int id[MAXM];
void precomp(bool b) {
iota(id, id + m, 1);
sort(id, id + m, [&] (int l, int r) {
return ab[l].FI > ab[r].FI;
});
REP (i, 1, n + 1) {
fw[i] = {-INF, 0};
}
REP (_, 0, m) {
int i = id[_];
if (ab[i].FI > ab[i].SE) {
continue;
}
(b ? p[0][i].FI : p[0][i].SE) = qmx(ab[i].SE).SE;
upd(ab[i].FI, {ab[i].SE, i});
}
sort(id, id + m, [&] (int l, int r) {
auto get = [&] (int i) {
return ab[i].FI < ab[i].SE ? ab[i].FI :
max(ab[i].FI - k + 1, ab[i].SE);
};
return get(l) > get(r);
});
REP (i, 1, n + 1) {
fw[i] = {-INF, 0};
}
REP (_, 0, m) {
int i = id[_];
if (ab[i].FI > ab[i].SE) {
upd(max(ab[i].FI - k + 1, ab[i].SE), {-ab[i].SE, i});
} else {
(b ? p[0][i].SE : p[0][i].FI) = qmx(ab[i].SE).SE;
}
}
sort(id, id + m, [&] (int l, int r) {
return ab[l].SE > ab[r].SE;
});
DSU::init();
REP (_, 0, m) {
int i = id[_];
if (ab[i].FI > ab[i].SE) {
continue;
}
while (DSU::rt[DSU::findp(ab[i].FI)] <= min(ab[i].SE, ab[i].FI + k - 1)) {
int x = DSU::rt[DSU::findp(ab[i].FI)];
(b ? src[n - x + 1].FI : src[x].SE) = i;
DSU::join(x, x + 1);
}
}
}
inline ii jump(ii x, int k) {
ii res = {0, 0};
auto relax = [&] (ii y) {
if (y.FI) {
if (!x.FI || ab[x.FI].SE > ab[y.FI].SE) {
res.FI = y.FI;
}
}
if (y.SE) {
if (!x.SE || ab[x.SE].SE < ab[y.SE].SE) {
res.SE = y.SE;
}
}
};
if (x.FI) {
relax(p[k][x.FI]);
}
if (x.SE) {
relax(p[k][x.SE]);
}
return res;
}
int main() {
#ifndef DEBUG
ios::sync_with_stdio(0), cin.tie(0);
#endif
cin >> n >> k;
cin >> m;
REP (i, 1, m + 1) {
cin >> ab[i].FI >> ab[i].SE;
}
REP (b, 0, 2) {
precomp(b);
REP (i, 1, m + 1) {
ab[i].FI = n - ab[i].FI + 1;
ab[i].SE = n - ab[i].SE + 1;
}
}
REP (k, 1, MAXL) {
REP (i, 1, m + 1) {
p[k][i] = jump(p[k - 1][i], k - 1);
}
}
REP (i, 1, m + 1) {
cerr << i << ": " << p[0][i].FI << ' ' << p[0][i].SE << '\n';
}
REP (i, 1, n + 1) {
cerr << i << ": " << src[i].FI << ' ' << src[i].SE << '\n';
}
cin >> q;
REP (i, 0, q) {
int s, t; cin >> s >> t;
ii u = src[s];
if (s < t) {
if (u.SE && ab[u.SE].SE >= t) {
cout << 1 << '\n';
continue;
}
} else {
cerr << ' ' << u.FI << ' ' << ab[u.FI].SE << '\n';
if (u.FI && ab[u.FI].SE <= t) {
cout << 1 << '\n';
continue;
}
}
int res = 2;
RREP (k, MAXL - 1, 0) {
ii v = jump(u, k);
if (s < t) {
if (v.SE && ab[v.SE].SE < t) {
u = v;
res += 1 << k;
}
} else {
if (v.FI && ab[v.FI].SE > t) {
u = v;
res += 1 << k;
}
}
}
u = jump(u, 0);
if (s < t) {
if (!u.SE || ab[u.SE].SE < t) {
res = -1;
}
} else {
if (!u.FI || ab[u.FI].SE > t) {
res = -1;
}
}
cout << res << '\n';
}
return 0;
}
# | 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... |